相机(摄像头)获取到的图片自动旋转90度解决办法
2016-07-12 14:20
344 查看
用相机拍摄出来的照片含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息。
如果我们忽略orientation信息,而直接对照片进行像素处理或者drawInRect等操作,得到的结果是翻转或者旋转90之后的样子。这是因为我们执行像素处理或者drawInRect等操作之后,imageOrientaion信息被删除了,imageOrientaion被重设为0,造成照片内容和imageOrientaion不匹配。
所以,在对照片进行处理之前,先将照片旋转到正确的方向,并且返回的imageOrientaion为0。
下面这个方法就是一个UIImage category中的方法,用它可以达到以上目的。
- (UIImage *)fixOrientation:(UIImage *)aImage
{
// No-op if the orientation is already correct
if (aImage.imageOrientation == UIImageOrientationUp)
{
return aImage;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (aImage.imageOrientation)
{
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
}
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
}
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
{
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
}
break;
default:
break;
}
switch (aImage.imageOrientation)
{
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
break;
default:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL,
aImage.size.width,
aImage.size.height,
CGImageGetBitsPerComponent(aImage.CGImage),
0,
CGImageGetColorSpace(aImage.CGImage),
CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (aImage.imageOrientation)
{
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
{
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
}
break;
default:
{
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
}
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage * img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
如果我们忽略orientation信息,而直接对照片进行像素处理或者drawInRect等操作,得到的结果是翻转或者旋转90之后的样子。这是因为我们执行像素处理或者drawInRect等操作之后,imageOrientaion信息被删除了,imageOrientaion被重设为0,造成照片内容和imageOrientaion不匹配。
所以,在对照片进行处理之前,先将照片旋转到正确的方向,并且返回的imageOrientaion为0。
下面这个方法就是一个UIImage category中的方法,用它可以达到以上目的。
- (UIImage *)fixOrientation:(UIImage *)aImage
{
// No-op if the orientation is already correct
if (aImage.imageOrientation == UIImageOrientationUp)
{
return aImage;
}
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (aImage.imageOrientation)
{
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
}
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
}
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
{
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
}
break;
default:
break;
}
switch (aImage.imageOrientation)
{
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
{
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
}
break;
default:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL,
aImage.size.width,
aImage.size.height,
CGImageGetBitsPerComponent(aImage.CGImage),
0,
CGImageGetColorSpace(aImage.CGImage),
CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (aImage.imageOrientation)
{
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
{
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
}
break;
default:
{
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
}
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage * img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
相关文章推荐
- Strategy设计模式之Comparable&Comparator接口
- asp.net mvc 分页 CPager(秒杀杨涛MvcPager)之封装之前
- leetcode_c++:哈希:Top K Frequent Elements(347)
- Path Sum II
- ORA-30078报错的两种解决方案
- MongoDB使用
- MultiViewPager项目的使用
- NYOJ2 括号配对
- js的for in具有不适应性(转)
- linux进程地址空间--vma的基本操作【转】
- 自定义webView,实现带title和返回的webView,监听webView的滑动事件
- sql语句判断两个时间段是否有交集
- study plane
- 一款新闻类iOS APP的诞生过程(初学)
- 为什么CPU到蓝牙的音频传输都是用的PCM接口呢
- Netty权威指南读书笔记
- iOS照片框架
- OpenWRT移植到三星S5PV210处理器上
- 从源代码的角度分析--在BaseAdapter调用notifyDataSetChanged()之后发生了什么
- 简单验证码识别