如何处理IOS图像裁剪中的图像旋转问题
Posted
技术标签:
【中文标题】如何处理IOS图像裁剪中的图像旋转问题【英文标题】:how to handle Image rotation issue in IOS image cropping 【发布时间】:2013-04-12 05:49:40 【问题描述】:我正在开发与相机相关的应用程序。这里我正在从相机拍摄图像,需要对其进行裁剪,然后将其修复为图像视图。为了裁剪图像,我正在使用 OpenGL。我的问题是我在裁剪图像之后是旋转 180 度。但这并非一直发生。有时我会得到原始图像本身。
-(void)showResult
NSLog(@"showResult called" );
UIImage *imageCrop;
float scaleCrop;
if (_sourceImage.size.width >= IMAGEWIDTH)
scaleCrop = IMAGEWIDTH / _sourceImage.size.width;
imageCrop = [ImageCropViewController scaleImage:_sourceImage with:CGSizeMake(_sourceImage.size.width*scaleCrop, _sourceImage.size.height*scaleCrop)];
else
scaleCrop = 1;
imageCrop = _sourceImage;
float scale = _sourceImage.size.width / resizeImage.size.width * 2;
IplImage *iplImage = [ImageCropViewController CreateIplImageFromUIImage:imageCrop] ;
Quadrilateral rectan;
rectan.point[0].x = _touchLayer.rectan.pointA.x*scale*scaleCrop;
rectan.point[0].y = _touchLayer.rectan.pointA.y*scale*scaleCrop;
rectan.point[1].x = _touchLayer.rectan.pointB.x*scale*scaleCrop;
rectan.point[1].y = _touchLayer.rectan.pointB.y*scale*scaleCrop;
rectan.point[2].x = _touchLayer.rectan.pointC.x*scale*scaleCrop;
rectan.point[2].y = _touchLayer.rectan.pointC.y*scale*scaleCrop;
rectan.point[3].x = _touchLayer.rectan.pointD.x*scale*scaleCrop;
rectan.point[3].y = _touchLayer.rectan.pointD.y*scale*scaleCrop;
IplImage* dest = cropDoc2(iplImage,rectan);
IplImage *image = cvCreateImage(cvGetSize(dest), IPL_DEPTH_8U, dest->nChannels);
cvCvtColor(dest, image, CV_BGR2RGB);
cvReleaseImage(&dest);
tempImage = [ImageCropViewController UIImageFromIplImage:image withImageOrientation:_sourceImage.imageOrientation];
[self crop:tempImage];
cvReleaseImage(&image);
之后调用下面的方法
+ (UIImage *)UIImageFromIplImage:(IplImage *)image withImageOrientation:(UIImageOrientation)orientation
NSLog(@"UIImageFromIplImage called" );
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData *data = [NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(image->width, image->height, image->depth, image->depth * image->nChannels, image->widthStep, colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);
UIImage *ret = [UIImage imageWithCGImage:imageRef scale:1 orientation:orientation];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ret;
然后我根据我的要求旋转图像
-(void)crop:(UIImage*)image
NSLog(@"crop called" );
//Adjust the image size, to scale the image to 1013 of width
float targetWidth = 1009.0f;
float scale = targetWidth / image.size.width;
float scaleheight = image.size.height * scale;
UIImage *imageToSent = [ImageCropViewController scaleImage:image with:CGSizeMake(targetWidth, scaleheight)];
if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
NSLog(@"###########Image orientation is UIInterfaceOrientationLandscapeLeft###########");
imageToSent = [[UIImage alloc] initWithCGImage:imageToSent.CGImage scale:1.0f orientation:UIImageOrientationDown];
NSData *imageData = UIImageJPEGRepresentation(imageToSent,0.75);
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
appDelegate.imagefilePath= [NSString stringWithFormat:@"%@/%@.jpg", DOCUMENTS_FOLDER,caldate];
[imageData writeToFile:appDelegate.imagefilePath atomically:YES];
appDelegate.cropimage=imageToSent;
我没有找到出错的地方。这正在浪费我的时间。请帮助我。
提前致谢
【问题讨论】:
删除这个 if 并尝试 if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) 你为什么用这个? 【参考方案1】:我有这个裁剪代码。你为什么使用openGL。这是我的代码。
- (UIImage *)cropImage : (UIImage*)myImage withRect:(CGRect)rect
CGImageRef imageRef = CGImageCreateWithImageInRect([myImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return img;
只要您想裁剪图像,只需调用此方法即可。此外,当您从相机或画廊拍摄图像(从本机相机应用程序拍摄的图像)时,您将获得旋转图像。使用此代码将其恢复为原始图像。
//----rotate image if picked from gallery or camera----//
- (UIImage *)scaleAndRotateImage:(UIImage *)image
NSLog(@"scaleAndRotateImage");
static int kMaxResolution = 640; // this is the maximum resolution that you want to set for an image.
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution)
CGFloat ratio = width/height;
if (ratio > 1)
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
else
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient)
case UIImageOrientationUp:
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored:
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown:
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored:
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationLeft:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationRightMirrored:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
case UIImageOrientationRight:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
default:
[NSException raise:NSInternalInconsistencyException
format:@"Invalid image orientation"];
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
else
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(),
CGRectMake(0, 0, width, height), imgRef);
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return returnImage;
希望我能帮上忙。
【讨论】:
我们试过了,但我们需要为裁剪线/点设置动画,这就是我们使用 OpenGl 的原因 动画裁剪线是什么意思? 边缘点应该向任何方向移动,而不仅仅是方形/矩形以上是关于如何处理IOS图像裁剪中的图像旋转问题的主要内容,如果未能解决你的问题,请参考以下文章