2009-04-07 30 views
8

Cập nhật:UIImagePickerĐiều chỉnh chỉnh sửa cho phép khóa UIImage để kích thước tối đa 320x320

Với iPhone OS 3.0+, toàn bộ UIImagePickerController API đã thay đổi. Câu hỏi và câu trả lời này cần được xem xét 2.2. mã kế thừa.


Khi sử dụng UIImagePickerController và bạn cho phép chỉnh sửa hình ảnh. IPhone cho phép người dùng thay đổi kích thước và xoay hình ảnh. Tuy nhiên, kích thước tối đa của hình ảnh đã chỉnh sửa bị giới hạn ở 320x320.

Ví dụ: tôi chụp ảnh màn hình iPhone và đặt nó trong thư viện ảnh, là 480x320 png. Khi tôi sử dụng UIImagePickerController để chọn hình ảnh đó, ngay cả khi tôi KHÔNG mở rộng hoặc xoay hình ảnh, nó sẽ bị cắt thành 320x320 trước khi nó được trả về từ UIImagePickerController. Tuy nhiên, nếu tôi tắt chỉnh sửa, hình ảnh sẽ được trả về kích thước 480x320 phù hợp.

Lý thuyết của tôi: Rất tinh tế, iPhone hiển thị 2 thanh công cụ mờ chuẩn không phủ lên hình ảnh. Những thanh công cụ này để lại một cửa sổ 320x320 "vô thưởng vô phạt" trên ảnh. Nó xuất hiện với tôi rằng cửa sổ này có hiệu quả clip ảnh cơ bản.

Lưu ý: Gọi lại cũng trả về một từ điển chỉnh sửa với hình ảnh gốc và cắt trực tiếp, nhưng tất nhiên rect cũng tối đa 320x320.

Bất kỳ ý tưởng nào về cách cho phép hình ảnh lớn hơn 320x320 được thu nhỏ và quét?

Một số mã:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo { 

     self.myImageView.userInteractionEnabled=YES; 
     CGRect imageFrame = myImageView.frame; 
     CGPoint imageCenter = myImageView.center; 
     imageFrame.size = img.size; 
     myImageView.frame = imageFrame; 
     self.myImageView.image = img; 
     myImageView.center = imageCenter; 

     [self dismissModalViewControllerAnimated:YES]; 
     [self performSelector:@selector(hideToolBars) withObject:nil afterDelay:2.0]; 
    } 
+0

Tôi vẫn thấy sự cố này trên 3.0.1, điều này có được khắc phục trong 3.1 không? – Jasarien

Trả lời

7

Như craig nói, đây là một vấn đề trong các diễn đàn dev và táo diễn đàn thảo luận thông thường. Tôi đã làm, tuy nhiên, tìm một cách xung quanh nó. Tôi đang sử dụng một chút mã từ:

Apple Dev Forums

này bao gồm hầu hết những gì bạn cần, và sẽ chăm sóc của tất cả các vấn đề định hướng camera. Tôi đã thêm những điều sau đây sẽ diễn trong thông tin chỉnh sửa và sử dụng nó để có được rect cắt xén ban đầu với cạnh này:

- (UIImage*)scaleImage:(UIImage*)anImage withEditingInfo:(NSDictionary*)editInfo{ 

    UIImage *newImage; 

    UIImage *originalImage = [editInfo valueForKey:@"UIImagePickerControllerOriginalImage"]; 
    CGSize originalSize = CGSizeMake(originalImage.size.width, originalImage.size.height); 
    CGRect originalFrame; 
    originalFrame.origin = CGPointMake(0,0); 
    originalFrame.size = originalSize; 

    CGRect croppingRect = [[editInfo valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue]; 
    CGSize croppingRectSize = CGSizeMake(croppingRect.size.width, croppingRect.size.height); 

    CGSize croppedScaledImageSize = anImage.size; 

    float scaledBarClipHeight = 80; 

    CGSize scaledImageSize; 
    float scale; 

    if(!CGSizeEqualToSize(croppedScaledImageSize, originalSize)){ 

     scale = croppedScaledImageSize.width/croppingRectSize.width; 
     float barClipHeight = scaledBarClipHeight/scale; 

     croppingRect.origin.y -= barClipHeight; 
     croppingRect.size.height += (2*barClipHeight); 

     if(croppingRect.origin.y<=0){ 
      croppingRect.size.height += croppingRect.origin.y; 
      croppingRect.origin.y=0; 
     } 

     if(croppingRect.size.height > (originalSize.height - croppingRect.origin.y)){ 
      croppingRect.size.height = (originalSize.height - croppingRect.origin.y); 
     } 


     scaledImageSize = croppingRect.size; 
     scaledImageSize.width *= scale; 
     scaledImageSize.height *= scale; 

     newImage = [self cropImage:originalImage to:croppingRect andScaleTo:scaledImageSize]; 

    }else{ 

     newImage = originalImage; 

    } 

    return newImage; 
} 

tôi cập nhật các cuộc gọi trở lại phương pháp từ các diễn đàn dev gửi như sau:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo { 

    [self dismissModalViewControllerAnimated:YES]; 
    self.myImageView.userInteractionEnabled=YES; 
    CGRect imageFrame = myImageView.frame; 
    CGPoint imageCenter = myImageView.center; 
    UIImage *croppedImage; 


    NSMutableDictionary *imageDescriptor = [editInfo mutableCopy]; 

    // CGFloat scaleSize = 400.0f; 
    CGFloat scaleSize = 640.0f; 
    switch ([picker sourceType]) { 
      //done 
     case UIImagePickerControllerSourceTypePhotoLibrary: 
      croppedImage = [self scaleImage:img withEditingInfo:editInfo]; 
      [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
      break; 


     case UIImagePickerControllerSourceTypeCamera: { 
      UIImageOrientation originalOrientation = [[editInfo objectForKey:UIImagePickerControllerOriginalImage] imageOrientation]; 
      if (originalOrientation != UIImageOrientationUp) { 
       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
       CGRect origRect; 
       [[editInfo objectForKey:UIImagePickerControllerCropRect] getValue:&origRect]; 
       UIImage *rotatedImage = straightenAndScaleImage([editInfo objectForKey:UIImagePickerControllerOriginalImage], scaleSize); 
       CGFloat scale = scaleSize/1600.0f; 
       origRect.origin.x *= scale; 
       origRect.origin.y *= scale; 
       origRect.size.width *= scale; 
       origRect.size.height *= scale; 
       croppedImage = [self cropImage:rotatedImage to:origRect andScaleTo:CGSizeMake(320, 480)]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
       [pool drain]; 
      } 
      else { 
       croppedImage = [self scaleImage:img withEditingInfo:editInfo]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
      } 
     } 
      break; 

     case UIImagePickerControllerSourceTypeSavedPhotosAlbum: { 
      UIImageOrientation originalOrientation = [[editInfo objectForKey:UIImagePickerControllerOriginalImage] imageOrientation]; 
      if (originalOrientation != UIImageOrientationUp) { 
       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
       CGRect origRect; 
       [[editInfo objectForKey:UIImagePickerControllerCropRect] getValue:&origRect]; 
       UIImage *rotatedImage = straightenAndScaleImage([editInfo objectForKey:UIImagePickerControllerOriginalImage], scaleSize); 
       CGFloat scale = scaleSize/640.0f; 
       origRect.origin.x *= scale; 
       origRect.origin.y *= scale; 
       origRect.size.width *= scale; 
       origRect.size.height *= scale; 
       croppedImage = [self cropImage:rotatedImage to:origRect andScaleTo:CGSizeMake(320, 480)]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
       [pool drain]; 
      } 
      else { 
       croppedImage = [self scaleImage:img withEditingInfo:editInfo]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
      } 
     } 
      break; 
     default: 
      break; 
    } 

    imageFrame.size = croppedImage.size; 
    myImageView.frame = imageFrame; 
    myImageView.image = [imageDescriptor objectForKey:@"croppedImage"]; 
    myImageView.center = imageCenter; 


} 
+0

Thay vì làm: CGSize originalSize = CGSizeMake (originalImage.size.width, originalImage.size.height); bạn chỉ có thể thực hiện CGSize originalSize = originalImage.size.width; –

+0

@Frank - Tôi nghĩ bạn có nghĩa là bạn chỉ có thể làm CGSize originalSize = originalImage.size; – Brian

+0

@Brian - Đúng, đó là ý của tôi. Bạn không chắc chắn cách .width có trong đó. Bạn sẽ nhận được một số loại huy hiệu để nhận sai lầm 3 năm tuổi! –

1

Điều này dường như là một trở ngại của SDK, ít nhất là khi thiết lập các allowsImageEditing TRUE trên bảng chọn hình ảnh. Có một chút của cuộc thảo luận về chủ đề này trong các diễn đàn của Apple ở đây:

http://discussions.apple.com/message.jspa?messageID=7841993

1

muộn còn hơn không: đây là nguồn cho các chức năng orientationTransformForImage

 

CGAffineTransform orientationTransformForImage(UIImage *image, CGSize *newSize) { 
    CGImageRef img = [image CGImage]; 
    CGFloat width = CGImageGetWidth(img); 
    CGFloat height = CGImageGetHeight(img); 
    CGSize size = CGSizeMake(width, height); 
    CGAffineTransform transform = CGAffineTransformIdentity; 
    CGFloat origHeight = size.height; 
    UIImageOrientation orient = image.imageOrientation; 
    switch(orient) { /* EXIF 1 to 8 */ 
     case UIImageOrientationUp: 
      break; 
     case UIImageOrientationUpMirrored: 
      transform = CGAffineTransformMakeTranslation(width, 0.0f); 
      transform = CGAffineTransformScale(transform, -1.0f, 1.0f); 
      break; 
     case UIImageOrientationDown: 
      transform = CGAffineTransformMakeTranslation(width, height); 
      transform = CGAffineTransformRotate(transform, M_PI); 
      break; 
     case UIImageOrientationDownMirrored: 
      transform = CGAffineTransformMakeTranslation(0.0f, height); 
      transform = CGAffineTransformScale(transform, 1.0f, -1.0f); 
      break; 
     case UIImageOrientationLeftMirrored: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeTranslation(height, width); 
      transform = CGAffineTransformScale(transform, -1.0f, 1.0f); 
      transform = CGAffineTransformRotate(transform, 3.0f * M_PI/2.0f); 
      break; 
     case UIImageOrientationLeft: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeTranslation(0.0f, width); 
      transform = CGAffineTransformRotate(transform, 3.0f * M_PI/2.0f); 
      break; 
     case UIImageOrientationRightMirrored: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeScale(-1.0f, 1.0f); 
      transform = CGAffineTransformRotate(transform, M_PI/2.0f); 
      break; 
     case UIImageOrientationRight: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeTranslation(height, 0.0f); 
      transform = CGAffineTransformRotate(transform, M_PI/2.0f); 
      break; 
     default: 
      ; 
    } 
    *newSize = size; 
    return transform; 
} 
5

tôi phải là quá muộn để trả lời câu hỏi này, nhưng tôi đã có một cách tốt hơn t o hoàn thành công việc này.

static inline double radians (double degrees) {return degrees * M_PI/180;} 

+(UIImage*)editedImageFromMediaWithInfo:(NSDictionary*)info{ 
    if(![info objectForKey:UIImagePickerControllerCropRect])return nil; 
    if(![info objectForKey:UIImagePickerControllerOriginalImage])return nil; 

    UIImage *originalImage=[info objectForKey:UIImagePickerControllerOriginalImage]; 
    CGRect rect=[[info objectForKey:UIImagePickerControllerCropRect] CGRectValue]; 

    CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], rect); 

    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 
    CGContextRef bitmap = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    if (originalImage.imageOrientation == UIImageOrientationLeft) { 
     CGContextRotateCTM (bitmap, radians(90)); 
     CGContextTranslateCTM (bitmap, 0, -rect.size.height); 

    } else if (originalImage.imageOrientation == UIImageOrientationRight) { 
     CGContextRotateCTM (bitmap, radians(-90)); 
     CGContextTranslateCTM (bitmap, -rect.size.width, 0); 

    } else if (originalImage.imageOrientation == UIImageOrientationUp) { 
     // NOTHING 
    } else if (originalImage.imageOrientation == UIImageOrientationDown) { 
     CGContextTranslateCTM (bitmap, rect.size.width, rect.size.height); 
     CGContextRotateCTM (bitmap, radians(-180.)); 
    } 

    CGContextDrawImage(bitmap, CGRectMake(0, 0, rect.size.width, rect.size.height), imageRef); 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 

    UIImage *resultImage=[UIImage imageWithCGImage:ref]; 
    CGImageRelease(imageRef); 
    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return resultImage; 
} 

Nó chỉ cắt một phần ảnh gốc với CropRect tương đối, mặc dù điều này quy mô phương pháp doesnt hình ảnh, nhưng nó là ngắn và ngọt ngào cho tôi. Chỉ cần để tham khảo :)

2

Với iPhone OS 3.0+, toàn bộ UIImagePickerController API đã thay đổi. Câu hỏi và câu trả lời cần được xem xét 2.2. mã kế thừa.

Mặc dù cảnh báo của bạn, nó đã cho tôi một giờ dev quý giá để nhận ra iOS 3.0+ đã cho chúng tôi UIImagePickerControllerEditedImage mà làm cho đối phó với tay cắt xén để của người dùng nhúm/zoom và đối phó với định hướng không cần thiết.

Đây là trường hợp bất kỳ ai vẫn đang sử dụng UIImagePickerControllerOriginalImage và cố gắng tìm ra cách tốt nhất để áp dụng cắt xén thông qua UIImagePickerControllerCropRect, v.v. Không còn cần thiết nữa.

0

Tôi đã viết một category on UIImage cung cấp cây trồng có độ phân giải đầy đủ. Cách dễ nhất để cài đặt là với CocoaPods, bằng cách thêm UIImage-ImagePickerCrop vào tệp podfile của bạn.

#import <UIImage+ImagePickerCrop.h> 

... 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info { 
    [self dismissViewControllerAnimated:YES completion:nil]; 

    UIImage *croppedImage = [UIImage croppedImageWithImagePickerInfo:info]; 
    ... 
} 
Các vấn đề liên quan