1

I was wondering if it's possible to "extract" a part of UIImageView.

For example, I select using Warp Affine a part of the UIImageView and I know the selected part frame.

like in this image:

enter image description here

Is it possible to get from the original UIImageView only the selected part without losing quality?

rcs
  • 67,191
  • 22
  • 172
  • 153

2 Answers2

7

Get the snapshot of the view via category method:

@implementation UIView(Snapshot)

-(UIImage*)makeSnapshot
{
  CGRect wholeRect = self.bounds;

  UIGraphicsBeginImageContextWithOptions(wholeRect.size, YES, [UIScreen mainScreen].scale);

  CGContextRef ctx = UIGraphicsGetCurrentContext();
  [[UIColor blackColor] set];
  CGContextFillRect(ctx, wholeRect);
  [self.layer renderInContext:ctx];

  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();

  UIGraphicsEndImageContext();

  return image;
}

@end

then crop it to your rect via another category method:

@implementation UIImage(Crop)

-(UIImage*)cropFromRect:(CGRect)fromRect
{
  fromRect = CGRectMake(fromRect.origin.x * self.scale,
                        fromRect.origin.y * self.scale,
                        fromRect.size.width * self.scale,
                        fromRect.size.height * self.scale);
  CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, fromRect);
  UIImage* crop = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
  CGImageRelease(imageRef);
  return crop;
}

@end

in your VC:

UIImage* snapshot = [self.imageView makeSnapshot];
UIImage* imageYouNeed = [snapshot cropFromRect:selectedRect];

selectedRect should be in you self.imageView coordinate system, if no so then use selectedRect = [self.imageView convertRect:selectedRect fromView:...]

Alexey Kozhevnikov
  • 4,249
  • 1
  • 21
  • 29
  • I'm sorry but your image cropping method is not working good. It seems to return a random part of the image, not the selected one. I'm currently using this method: http://pastie.org/private/wxmefesfdsu30vxf8un7q It seems to work pretty good, but it's a bit inaccurate, maybe you could help me fixing it ? For example, if I make a shot of the iPhone screen, and select it all, it return all the selected iPhone screen without the status bar. – Giuliano Zanco Dec 26 '12 at 21:33
  • Oh, the latter is not the UIImageView's method, but UIImage category method. First you need to get the UIImageView's snapshot, then crop snapshot with the latter method. – Alexey Kozhevnikov Dec 26 '12 at 21:42
  • Man, I tried again you method as you said and now it work 'well' like the one I posted. But it still is inaccurate, it's not 100% perfect, as mine. Can I make a little video to show you ? Thanks a lot. – Giuliano Zanco Dec 26 '12 at 22:48
  • See the edit. In what coordinate system is your selected rect? – Alexey Kozhevnikov Dec 27 '12 at 09:40
0

Yes, it's possibile.First you should get the UIImageView's image, using this property:

@property(nonatomic, retain) UIImage *image;

And NSImage's :

@property(nonatomic, readonly) CGImageRef CGImage;

Then you get the cut image:

CGImageRef cutImage = CGImageCreateWithImageInRect(yourCGImageRef, CGRectMake(x, y, w, h));

If you want again a UIImage you should use this UIImage's method:

+ (UIImage *)imageWithCGImage:(CGImageRef)cgImage;

PS: I don't know how to do it directly, without convert it to CGImageRef, maybe there's a way.

Ramy Al Zuhouri
  • 21,580
  • 26
  • 105
  • 187
  • Show what you've tried, x,y,w,h are just symbolic, what coordinates are you using and what are the view coordinates? – Ramy Al Zuhouri Dec 26 '12 at 16:04
  • UIImageView coordinates are: 20,8,280,400. Selected part of the UIImageView coordinates are: 31,255.5,262,142. – Giuliano Zanco Dec 26 '12 at 16:06
  • You are going out of bounds, the origin is (20,8) and the other points are the width/height.So for example if you want the lower part of the image you write x=220,y=300, w=60, h=100.If this doen't take the exact coordinates, try to slightly change the rect coordinates and size.Btw I'm not sure that the same of the UIImage. – Ramy Al Zuhouri Dec 26 '12 at 16:17