Ошибка UIImagePickerController
Я думаю, что нашел ошибку в последней версии iOS 7, запустив приложение с базовым SDK, установленным в iOS 6.1 (возможно, даже более низкие версии, еще не проверил это)
У меня есть это изображение в моей библиотеке фотографий: 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];
}
Это результирующее изображение:
![enter image description here]()
Обратите внимание на большую черную полосу справа. Что вызывает это?
Чтобы воспроизвести это, вам нужно:
- iOS 7
- Приложение с базовым SDK установлено на 6.1 (возможно, даже более низкие SDK тоже, я еще не пробовал)
- iPhone 5/5c/5s
- Случается только с изображениями, которые были сделаны с камерой iPhone 5/5c/5s (вы можете использовать исходное изображение, которое я связал выше для тестирования).
ПРИМЕЧАНИЕ.. Чтобы быть чистым, черная полоса является частью фактического изображения. Изображение, которое вы видите там, не является скриншотом UIImageView, но фактическое изображение, сохраненное на диске и загруженное здесь...
Ответы
Ответ 1
Ваш вопрос: "Что вызывает это?" Поэтому я сосредоточусь на этом, а не на обходном пути.
Это определенно ошибка в iOS 7, работающая с отредактированными изображениями в базовых SDK. Мы также можем исключить, что XCode 5 и Base SDK 6.1 вызвали это, потому что я получаю ту же самую проблему с XCode 4.6.3 и 6.1 SDK, работающим на iOS 7 Simulator.
Источником проблемы является то, что значения CropRect, которые вычисляются SDK, являются неправильными.
Если вы распечатаете info
NSDictionary
из imagePickerController:didFinishPickingMediaWithInfo
, вы увидите, что:
iOS 7 работает с любым SDK ниже 7, мы получим:
UIImagePickerControllerCropRect = "NSRect: { {154, 495}, {1705, 1705}}";
Во время работы iOS 6 или 5 с их SDK мы получим:
UIImagePickerControllerCropRect = "NSRect: {{ 0, 149}, {1704, 1705}}";
Вы, вероятно, говорите, хм, эти значения меняются между SDK. Ну, да, если вы поместите свой снимок полностью и выберите его, вы также получите черную полосу внизу рисунка.
![enter image description here]()
Предлагаемые решения:
Edit - очень простое решение, добавленное поклонником ответа!
Удивительно, но это может быть просто и элегантно обрезать:
{
// 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];
}
Здесь вся обычная обычная рамка: toRect:
-(UIImage *)ordinaryCrop:(UIImage *)imageToCrop toRect:(CGRect)cropRect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], cropRect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
Теперь, как указывает Джесси, важно правильно поворачивать изображение. Эта абсолютно невероятная часть кода от Anomie делает работу:
iOS UIImagePickerController - результат ориентации изображения после загрузки
Фиксирование ориентации UIImage. UIImage + fixOrientation.h
Это так просто, надеюсь, что это поможет кому-то. Еще раз спасибо за бесценные ответы здесь.
Ответ 2
Я считаю, что мы столкнулись с подобными проблемами, не обращая внимания на отредактированное изображение напрямую; попросите исходное изображение и информацию об урожае (UIImagePickerControllerCropRect
) и сделайте обрезку самостоятельно. Обратите внимание, что вам нужно беспокоиться о поворотах исходного изображения, если вы сами обрезаете.
Вы можете найти ответ в этом вопросе, полезный для реализации этой работы.
Ответ 3
Программно запрограммируйте поиск и изменение режима (Aspect Fit, Aspect Fill, Scale to Fill).
Ответ 4
Я пытаюсь воспроизвести эту ошибку. И не повезло на симуляторе, симуляторе 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.