【问题标题】:iOS: Cropping a still image grabbed from a UIImagePickerController camera with overlayiOS:裁剪从 UIImagePickerController 相机抓取的静止图像,并带有叠加层
【发布时间】:2012-01-19 15:44:38
【问题描述】:

我是 iOS 新手,过去一周我一直在为此苦苦挣扎,在网上四处寻找教程,例如:Dealing with Exif ImagesResizing images,以及 StackOverflow 上的更多随机问题。从这些,我发现>=iOS 4.0,所有从相机拍摄的图像都包含基于EXIF的旋转信息。

什么不工作:尝试不同的图像裁剪技术后,我最终只是在一些随机角落裁剪图像,而且生成的图像似乎被放大了:(当我使用来自互联网的png 图像(不包含 EXIF 数据),裁剪正在工作。通过随机角,我的意思是 - 图像最终在右上角/左上角被裁剪并放大.

我想要完成的工作:
我正在尝试从顶部裁剪图像100 px,从底部裁剪100 px。本质上,我使用两个覆盖条 - 1 个在顶部,1 个在底部,CGRect(0.0, 0.0, SCREEN_WIDTH, 100.0) [顶部有一个 100.0 px 高条] 和另一个 CGRect(0.0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100.0) [另一个 100 px 底部的高条]。我需要在这两个条带之间获取图像:我假设图像的高度是:SCREEN_HEIGHT - 200.0

显示带有叠加层的相机的 UIImagePickerController:

//SCREEN_HEIGHT = 480 and SCREEN_WIDTH = 320 UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) { NSLog(@"Camera not available"); return; } imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; imagePicker.delegate = self; imagePicker.allowsEditing = NO; // Hide the controls imagePicker.showsCameraControls = NO; imagePicker.navigationBarHidden = YES; // Make camera view full screen imagePicker.wantsFullScreenLayout = YES; //imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y); //Overlay //OverlayView is a plain UIView with the CGRects mentioned in the question. OverlayView *overlay = [[OverlayView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; [overlay initOverlay:self]; imagePicker.cameraOverlayView = overlay; [self presentModalViewController:imagePicker animated:YES];

根据 EXIF imageOrientation 属性旋转图像并对其进行裁剪的代码

- (UIImage *) cropImage: (UIImage *) originalImage { CGRect cropRect = CGRectMake(0, 100.0, SCREEN_WIDTH, SCREEN_HEIGHT - 100); CGRect transformedRect = [self TransformCGRectForUIImageOrientation:cropRect :originalImage.imageOrientation :originalImage.size]; CGImageRef resultImageRef = CGImageCreateWithImageInRect(originalImage.CGImage, transformedRect); UIImage *newImage = [[[UIImage alloc] initWithCGImage:resultImageRef scale:1.0 orientation:originalImage.imageOrientation] autorelease]; return newImage; } - (CGRect) TransformCGRectForUIImageOrientation: (CGRect) source: (UIImageOrientation) orientation: (CGSize) imageSize { switch (orientation) { case UIImageOrientationLeft: { // EXIF #8 CGAffineTransform txTranslate = CGAffineTransformMakeTranslation( imageSize.height, 0.0); CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate, M_PI_2); return CGRectApplyAffineTransform(source, txCompound); } case UIImageOrientationDown: { // EXIF #3 CGAffineTransform txTranslate = CGAffineTransformMakeTranslation( imageSize.width, imageSize.height); CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate, M_PI); return CGRectApplyAffineTransform(source, txCompound); } case UIImageOrientationRight: { // EXIF #6 CGAffineTransform txTranslate = CGAffineTransformMakeTranslation( 0.0, imageSize.width); CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate, M_PI + M_PI_2); return CGRectApplyAffineTransform(source, txCompound); } case UIImageOrientationUp: // EXIF #1 - do nothing default: // EXIF 2,4,5,7 - ignore return source; }

cropImage 方法似乎适用于从 Internet 下载的图像(不包含任何方向信息)。 我的选择已经不多了。有人可以帮我吗?

感谢阅读!

【问题讨论】:

  • Sagar - 以下方法是否没有导致您的应用崩溃?
  • @Odelya 您指的是以下哪种方法?
  • 马特的回答。我有确切的问题,并且一个月没有成功正确裁剪图像
  • @Odelya 不,它非常适合我。你得到了什么错误?
  • 应用程序使用后崩溃。它消耗大量内存。我实际上是直接使用 AVFoundation,我需要裁剪图像

标签: iphone ios image-processing crop


【解决方案1】:

如果可以,使用 Core Graphics 更容易跳过绘制图像:

- (UIImage *)cropImage:(UIImage *)oldImage {
    CGSize imageSize = oldImage.size
    UIGraphicsBeginImageContextWithOptions( CGSizeMake( imageSize.width,
                                                        imageSize.height - 200),
                                            NO,
                                            0.);
    [oldImage drawAtPoint:CGPointMake( 0, -100)
                blendMode:kCGBlendModeCopy
                    alpha:1.];
    UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return croppedImage;
}

【讨论】:

  • +1 谢谢,马特。试图理解代码:第 2 行“选择”裁剪底部 200 像素的图像,然后将新图像放置在原始图像上方 100 像素处,从而裁剪顶部 100 像素和底部 100 像素,对吗?它对我有用!非常感谢您的努力!!虽然剪辑的图像与使用相机叠加层看到的图像并不完全相似,但我可能不得不调整编号。一点点。顺便说一句,这段代码不是线程安全的吗?而且我猜 CG 库提供了一种线程安全的方式来执行此操作 - 所以以线程安全的方式使用它会很棒。
  • 在 iOS 4.0 及更高版本上是线程安全的,QA 1637
  • +1,接受!太棒了,这很有效 - 太棒了!万分感谢!非常感谢!
  • 完美!我尝试了几种方法,考虑到图像方向,没有一种方法能按预期工作。我总是以旋转的图像结束。谢谢。
  • @Mats,有没有办法进行类似的裁剪,但还包括 x 偏移点?我的意思是像裁剪一个矩形,而不仅仅是顶部和底部?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2013-09-30
  • 1970-01-01
相关资源
最近更新 更多