【问题标题】:UIImagePickerController bugUIImagePickerController 错误
【发布时间】:2013-10-24 05:46:00
【问题描述】:

我认为我在运行一个将 Base SDK 设置为 iOS 6.1 的应用程序时发现了最新 iOS 7 中的一个错误(可能还有更低的版本,还没有测试过)

我的照片库中有这张图片:http://i.imgur.com/7KUIGLt.jpg

我通过以下方式呈现一个 UIImagePickerController:

UIImagePickerController *vc = [[UIImagePickerController alloc] init];
vc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
vc.delegate = self;
vc.allowsEditing = YES;
[self presentViewController:vc animated:YES completion:nil];

我将选择的图像保存到我的桌面(我在模拟器上运行它,但它也适用于设备)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage* outputImage = [info objectForKey:UIImagePickerControllerEditedImage];
    if (outputImage == nil) {
        outputImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    }
    NSData *d = UIImagePNGRepresentation(outputImage);
    [d writeToFile:@"/Users/Admin/Desktop/test.png" atomically:YES];
    [self dismissViewControllerAnimated:YES completion:nil];
}

这是生成的图像:

注意右边的大黑条。这是什么原因造成的?

要重现这个,你需要:

  • iOS 7
  • Base SDK 设置为 6.1 的应用程序(也许更低的 SDK,我还没有尝试过)
  • iPhone 5/5c/5s
  • 仅适用于使用 iPhone 5/5c/5s 相机拍摄的照片(您可以使用我上面链接的原始图像进行测试)

注意:为了清楚起见,黑条是实际图像的一部分。你看到的图片不是 UIImageView 的截图,而是保存到磁盘并上传到这里的实际图片...

【问题讨论】:

  • 你的来源设置为UIImagePickerControllerSourceTypePhotoLibrary,所以看起来你并没有使用实际的相机,而是从库中获取图像。对吧?
  • 我在编辑过的图片和/或旋转过的图片上看到过类似的问题。以其他方向拍摄的图像是否会发生这种情况?如果您不允许编辑,会发生这种情况吗?
  • 如果更改编辑矩形会发生这种情况吗?我们看到的这些问题之一只有在用户接受默认裁剪矩形时才会发生。
  • @Lefteris 是的,它仅在从库中选择图像时发生。如果它们是从应用程序中的相机拍摄的,它可以正常工作。
  • 你能澄清一下吗?这里有什么问题,黑条应该在那里吗?

标签: ios objective-c cocoa-touch ios7 uiimagepickercontroller


【解决方案1】:

您的问题是“是什么原因造成的?”因此,我将专注于这一点,而不是提供解决方法。 这绝对是 iOS 7 中处理较低基础 SDK 中编辑图像的错误。我们还可以排除 XCode 5 和 Base SDK 6.1 导致此问题,因为我在 iOS 7 模拟器上运行的 XCode 4.6.3 和 6.1 SDK 遇到了同样的问题。

问题的根源在于SDK计算的CropRect值不对。 如果您从imagePickerController:didFinishPickingMediaWithInfo 打印出info NSDictionary,您会看到:

运行任何低于 7 的 SDK 的 iOS 7 我们将获得:

UIImagePickerControllerCropRect = "NSRect: {{154, 495}, {1705, 1705}}";

使用他们的 SDK 运行 iOS 6 或 5 会给我们:

UIImagePickerControllerCropRect = "NSRect: {{0, 149}, {1704, 1705}}";

您可能会说,嗯,这些 y 值也在 SDK 之间发生变化。好吧,是的,如果您将图片一直向下滑动并选择它,您还会在图片底部看到一个黑条。

建议的解决方案:

  1. File a bug report to Apple here ...做到了!

  2. 不要使用UIImagePickerControllerEditedImage,而是拍摄原始照片。

  3. 自己计算并裁剪。

  4. 使用第 3 方裁剪库,例如 PEPhotoCropEditorSSPhotoCropperViewController


编辑 - 答案的粉丝添加的非常简单的解决方案!

令人惊讶的是,自己裁剪它可以如此简单和优雅:

{
// There is a bug in iOS. When using ALBUM, you must crop it yourself:

fromAlbum = [info objectForKey:UIImagePickerControllerOriginalImage];
fromAlbum = [fromAlbum fixOrientation];

CGRect crop = [[info valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue];
fromAlbum = [self ordinaryCrop:fromAlbum toRect:crop];
}

这是整个例程 normalCrop:toRect:

-(UIImage *)ordinaryCrop:(UIImage *)imageToCrop toRect:(CGRect)cropRect
 {
 CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], cropRect);
 UIImage *cropped = [UIImage imageWithCGImage:imageRef];
 CGImageRelease(imageRef);
 return cropped;
 }

正如 Jesse 指出的那样,正确旋转图像至关重要。 Anomie 的这段绝对令人难以置信的代码完成了这项工作:

iOS UIImagePickerController result image orientation after upload

修复 UIImage 方向 .. UIImage+fixOrientation.h

就是这么简单,希望对大家有所帮助。再次感谢这里无价的答案。

【讨论】:

  • 请注意... 2014 年 3 月 ... 这个错误仍然完全存在,即使在 iOS7 和仅适用于 iOS7 的应用程序中也是如此。 Segev 在 (3) 处的解决方案似乎是解决方案,感谢 Segev。
  • @JoeBlow 很棒的编辑。谢谢乔!我想知道这是否已在 7.1 beta 中修复
  • iOS 9 仍然存在(iPad mini 4)
  • @BobdeGraaf iOS 11 的错误实际上有点不同。见stackoverflow.com/q/48056398/368085。它不能像这样解决。
  • @mluisbrown 也许嗯,虽然那个是关于顶部/底部裁剪,而我实际上仍然遇到右侧黑条的问题。我能够使用此答案中的代码修复它:)
【解决方案2】:

我正在尝试重现此错误。并且在模拟器、64 位模拟器和 iPad mini 上没有运气。全部运行 iOS 7.0。

我将您的代码放入我的应用程序中:

UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];
if (!image)
    image = [info valueForKey:UIImagePickerControllerOriginalImage];

// Save photo to custom album only if taken by camera
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera)
    [ALAssetsLibrary saveImageToCustomAlbum:image
                                   assetURL:[info valueForKey:UIImagePickerControllerReferenceURL]];


NSData *d = UIImagePNGRepresentation(image);
[d writeToFile:@"/Volumes/Alko/Temp/test.png" atomically:YES];

UIImageWriteToSavedPhotosAlbum(image, nil, NULL, nil);

[self setImage:image];
[self dismissPicker:picker];
[self photoPickerDidFinish];

并且使用从http://i.imgur.com/7KUIGLt.jpg 下载的图像可以正常工作。 我认为您的应用程序有问题,而不是 UIImagePickerController。

【讨论】:

  • 您的 BaseSDK 设置为 iOS 6 还是 6.1?
  • 正如问题中所说,该错误不会出现在模拟器中。
【解决方案3】:

我相信我们最终解决了类似的问题,从未直接要求编辑过的图像;询问原始图像和裁剪信息(UIImagePickerControllerCropRect)并自己进行裁剪。请注意,如果您自己进行裁剪,则需要担心源图像中的旋转。

您可能会发现answer in this question 有助于实施此解决方法。

【讨论】:

    【解决方案4】:

    尝试以编程方式查找和更改模式(Aspect Fit、Aspect Fill、Scale to Fill)。

    【讨论】:

    • 黑条是实际图像的一部分。你看到的图片不是一个UIImageView的截图,而是实际保存到磁盘并上传到这里的图片...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多