Như các bạn đã quan sát UIImagePickerController sẽ trả về một thu nhỏ lại hình ảnh đã chỉnh sửa đôi khi 640x640 đôi khi 320x320 (thiết bị phụ thuộc).
Câu hỏi của bạn:
Làm thế nào tôi có thể làm một cắt vuông tới ảnh gốc là một hình ảnh 2448 * 2448?
Để thực hiện việc này, trước tiên bạn cần sử dụng UIImagePickerControllerCropRect
để tạo hình ảnh mới từ hình ảnh gốc thu được bằng cách sử dụng khóa UIImagePickerControllerOriginalImage
của từ điển thông tin. Sử dụng phương pháp Quartz Core, CGImageCreateWithImageInRect
bạn có thể tạo một hình ảnh mới chỉ chứa các điểm ảnh bị giới hạn bởi đường cong đã truyền; trong trường hợp này là cây trồng rect. Bạn sẽ cần phải đưa vào định hướng tài khoản để điều này hoạt động đúng. Sau đó, bạn chỉ cần quy mô hình ảnh theo kích thước mong muốn của bạn. Điều quan trọng cần lưu ý là crop rect có liên quan đến hình ảnh gốc khi nó được định hướng đúng, không phải khi nó xuất hiện từ thư viện ảnh hoặc thư viện ảnh. Đây là lý do tại sao chúng ta cần phải chuyển đổi crop rect để phù hợp với định hướng khi chúng ta bắt đầu sử dụng các phương thức Quartz để tạo ra các hình ảnh mới, v.v.
Tôi lấy mã của bạn ở trên và thiết lập mã để tạo hình ảnh 1280x1280 từ hình ảnh gốc dựa trên cây trồng trực tràng. Vẫn còn một số trường hợp cạnh ở đây, tức là có tính đến vụ cắt đôi có thể có giá trị âm, (mã giả định hình vuông cắt vuông góc) chưa được giải quyết.
- Đầu tiên chuyển đổi cắt trực tiếp để tính đến hướng của hình ảnh và kích thước đến. Chức năng này
transformCGRectForUIImageOrientation
là từ NiftyBean
- Tạo một hình ảnh được cắt thành trực tiếp cắt xén.
- Quy mô (và xoay) hình ảnh theo kích thước mong muốn. tức là 1280x1280.
- Tạo UIImage từ CGImage với quy mô và hướng chính xác.
Đây là mã của bạn với các thay đổi: CẬP NHẬT Mã mới đã được thêm vào bên dưới để đảm bảo các trường hợp bị thiếu.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:@"public.image"])
{
UIImage *imageEdited = [info objectForKey:UIImagePickerControllerEditedImage];
UIImage *imagePicked = [info objectForKey:UIImagePickerControllerOriginalImage];
CGRect cropRect;
cropRect = [[info valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue];
NSLog(@"Original width = %f height= %f ",imagePicked.size.width, imagePicked.size.height);
//Original width = 1440.000000 height= 1920.000000
NSLog(@"imageEdited width = %f height = %f",imageEdited.size.width, imageEdited.size.height);
//imageEdited width = 640.000000 height = 640.000000
NSLog(@"corpRect %@", NSStringFromCGRect(cropRect));
//corpRect 80.000000 216.000000 1280.000000 1280.000000
CGSize finalSize = CGSizeMake(1280,1280);
CGImageRef imagePickedRef = imagePicked.CGImage;
CGRect transformedRect = transformCGRectForUIImageOrientation(cropRect, imagePicked.imageOrientation, imagePicked.size);
CGImageRef cropRectImage = CGImageCreateWithImageInRect(imagePickedRef, transformedRect);
CGColorSpaceRef colorspace = CGImageGetColorSpace(imagePickedRef);
CGContextRef context = CGBitmapContextCreate(NULL,
finalSize.width,
finalSize.height,
CGImageGetBitsPerComponent(imagePickedRef),
CGImageGetBytesPerRow(imagePickedRef),
colorspace,
CGImageGetAlphaInfo(imagePickedRef));
CGContextSetInterpolationQuality(context, kCGInterpolationHigh); //Give the context a hint that we want high quality during the scale
CGContextDrawImage(context, CGRectMake(0, 0, finalSize.width, finalSize.height), cropRectImage);
CGImageRelease(cropRectImage);
CGImageRef instaImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
//assign the image to an UIImage Control
UIImage *image = [UIImage imageWithCGImage:instaImage scale:imagePicked.scale orientation:imagePicked.imageOrientation];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = image;
CGImageRelease(instaImage);
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}
[self dismissModalViewControllerAnimated:YES];
}
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;
}
}
CẬP NHẬT Tôi đã thực hiện một vài phương pháp mà sẽ chăm sóc phần còn lại của các trường hợp. Các bước cơ bản giống nhau, với một vài sửa đổi.
- sửa đổi đầu tiên là để chuyển đổi một cách chính xác và mở rộng bối cảnh để xử lý các định hướng của hình ảnh đến,
- và thứ hai là để hỗ trợ các loại cây trồng không vuông bạn có thể nhận được từ các
UIImagePickerController
. Trong những trường hợp này, hình vuông là được tô màu theo lựa chọn của bạn.
Mã New
// CropRect is assumed to be in UIImageOrientationUp, as it is delivered this way from the UIImagePickerController when using AllowsImageEditing is on.
// The sourceImage can be in any orientation, the crop will be transformed to match
// The output image bounds define the final size of the image, the image will be scaled to fit,(AspectFit) the bounds, the fill color will be
// used for areas that are not covered by the scaled image.
-(UIImage *)cropImage:(UIImage *)sourceImage cropRect:(CGRect)cropRect aspectFitBounds:(CGSize)finalImageSize fillColor:(UIColor *)fillColor {
CGImageRef sourceImageRef = sourceImage.CGImage;
//Since the crop rect is in UIImageOrientationUp we need to transform it to match the source image.
CGAffineTransform rectTransform = [self transformSize:sourceImage.size orientation:sourceImage.imageOrientation];
CGRect transformedRect = CGRectApplyAffineTransform(cropRect, rectTransform);
//Now we get just the region of the source image that we are interested in.
CGImageRef cropRectImage = CGImageCreateWithImageInRect(sourceImageRef, transformedRect);
//Figure out which dimension fits within our final size and calculate the aspect correct rect that will fit in our new bounds
CGFloat horizontalRatio = finalImageSize.width/CGImageGetWidth(cropRectImage);
CGFloat verticalRatio = finalImageSize.height/CGImageGetHeight(cropRectImage);
CGFloat ratio = MIN(horizontalRatio, verticalRatio); //Aspect Fit
CGSize aspectFitSize = CGSizeMake(CGImageGetWidth(cropRectImage) * ratio, CGImageGetHeight(cropRectImage) * ratio);
CGContextRef context = CGBitmapContextCreate(NULL,
finalImageSize.width,
finalImageSize.height,
CGImageGetBitsPerComponent(cropRectImage),
0,
CGImageGetColorSpace(cropRectImage),
CGImageGetBitmapInfo(cropRectImage));
if (context == NULL) {
NSLog(@"NULL CONTEXT!");
}
//Fill with our background color
CGContextSetFillColorWithColor(context, fillColor.CGColor);
CGContextFillRect(context, CGRectMake(0, 0, finalImageSize.width, finalImageSize.height));
//We need to rotate and transform the context based on the orientation of the source image.
CGAffineTransform contextTransform = [self transformSize:finalImageSize orientation:sourceImage.imageOrientation];
CGContextConcatCTM(context, contextTransform);
//Give the context a hint that we want high quality during the scale
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
//Draw our image centered vertically and horizontally in our context.
CGContextDrawImage(context, CGRectMake((finalImageSize.width-aspectFitSize.width)/2, (finalImageSize.height-aspectFitSize.height)/2, aspectFitSize.width, aspectFitSize.height), cropRectImage);
//Start cleaning up..
CGImageRelease(cropRectImage);
CGImageRef finalImageRef = CGBitmapContextCreateImage(context);
UIImage *finalImage = [UIImage imageWithCGImage:finalImageRef];
CGContextRelease(context);
CGImageRelease(finalImageRef);
return finalImage;
}
//Creates a transform that will correctly rotate and translate for the passed orientation.
//Based on code from niftyBean.com
- (CGAffineTransform) transformSize:(CGSize)imageSize orientation:(UIImageOrientation)orientation {
CGAffineTransform transform = CGAffineTransformIdentity;
switch (orientation) {
case UIImageOrientationLeft: { // EXIF #8
CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI_2);
transform = txCompound;
break;
}
case UIImageOrientationDown: { // EXIF #3
CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,M_PI);
transform = txCompound;
break;
}
case UIImageOrientationRight: { // EXIF #6
CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(0.0, imageSize.width);
CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate,-M_PI_2);
transform = txCompound;
break;
}
case UIImageOrientationUp: // EXIF #1 - do nothing
default: // EXIF 2,4,5,7 - ignore
break;
}
return transform;
}
Yeah! Nó hoạt động! Bạn có thể cho tôi biết tại sao UIImagePickerController không cho tôi hình ảnh gốc trong cuộn camera? – user1486413
Tôi không chắc chắn lý do đằng sau nó là gì. Tôi đã quan sát thấy rằng bạn chắc chắn có được một phiên bản độ phân giải đầy đủ khi chụp ảnh bằng máy ảnh. Nếu bạn cần có phiên bản độ phân giải đầy đủ, tôi nghĩ bạn có thể sử dụng 'UIImagePickerControllerReferenceURL' kết hợp với các lớp' ALAssetLibrary' để lấy nó. Sử dụng khung này sẽ yêu cầu người dùng của bạn cho phép truy cập vị trí của họ, vì hình ảnh gốc sẽ được gắn thẻ địa lý. –
Ngoài ra .. cập nhật mã để xử lý vòng quay an toàn hơn, và cũng xử lý việc nhận được một hình ảnh vuông ngay cả khi cây trồng rect không vuông. Hy vọng nó giúp. –