Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cropping image with transparency in iPhone

Tags:

I am working on Jigsaw type of game where i have two images for masking, I have implemented this code for masking

- (UIImage*) maskImage:(UIImage *)image withMaskImage:(UIImage*)maskImage {      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();     CGImageRef maskImageRef = [maskImage CGImage];      CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);      if (mainViewContentContext==NULL)         return NULL;      CGFloat ratio = 0;     ratio = maskImage.size.width/ image.size.width;     if(ratio * image.size.height < maskImage.size.height) {         ratio = maskImage.size.height/ image.size.height;     }       CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};     CGRect rect2  = {{-((image.size.width*ratio)-maskImage.size.width)/2,-((image.size.height*ratio)-maskImage.size.height)/2},{image.size.width*ratio, image.size.height*ratio}};      CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);     CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);      CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);     CGContextRelease(mainViewContentContext);      UIImage *theImage = [UIImage imageWithCGImage:newImage];     CGImageRelease(newImage);     return theImage; } 

enter image description here

+

enter image description here

=

This is final result i got after masking.

enter image description here

now i would like to crop image in piece like enter image description here and enter image description here and so on parametrically(crop an image by transparency).

if any one has implemented such code or any idea on this scenario please share.

Thanks.

I am using this line of code for as Guntis Treulands's suggestion

int i=1;     for (int x=0; x<=212; x+=106) {         for (int y=0; y<318; y+=106) {             CGRect rect = CGRectMake(x, y, 106, 106);             CGRect rect2x = CGRectMake(x*2, y*2, 212, 212);              UIImage *orgImg = [UIImage imageNamed:@"[email protected]"];             UIImage *frmImg = [UIImage imageNamed:[NSString stringWithFormat:@"%[email protected]",i]];             UIImage *cropImg = [self cropImage:orgImg withRect:rect2x];              UIImageView *tmpImg = [[UIImageView alloc] initWithFrame:rect];             [tmpImg setUserInteractionEnabled:YES];             [tmpImg setImage:[self maskImage:cropImg withMaskImage:frmImg]];              [self.view addSubview:tmpImg];             i++;         }     } 

orgImg is original cat image, frmImg frame for holding individual piece, masked in photoshop and cropImg is 106x106 cropped image of original [email protected].

my function for cropping is as following

- (UIImage *) cropImage:(UIImage*)originalImage withRect:(CGRect)rect {      return [UIImage imageWithCGImage:CGImageCreateWithImageInRect([originalImage CGImage], rect)];  } 
like image 637
iCoder86 Avatar asked May 30 '12 06:05

iCoder86


People also ask

How do you make a transparent cutout on iPhone?

At the bottom toolbar, there will be several editing options for the imported image. Select Cutout. Choose a cutout method. Select gives you multiple automated cutouts that you can neaten up with the Erase tool, while Outline lets you manually outline the subject that you want to isolate.

Can you save an image with a transparent background on an iPhone?

Go to your iCloud backup settings and change it from "Optimize storage" to "Download and keep originals" (additional information can be found here). Download/transfer the image with the transparent background to your device.


1 Answers

UPDATE 2

I became really curious to find a better way to create a Jigsaw puzzle, so I spent two weekends and created a demo project of Jigsaw puzzle.

It contains:

  • provide column/row count and it will generate necessary puzzle pieces with correct width/height. The more columns/rows - the smaller the width/height and outline/inline puzzle form.
  • each time generate randomly sides
  • can randomly position / rotate pieces at the beginning of launch
  • each piece can be rotated by tap, or by two fingers (like a real piece) - but once released, it will snap to 90/180/270/360 degrees
  • each piece can be moved if touched on its “touchable shape” boundary (which is mostly the - same visible puzzle shape, but WITHOUT inline shapes)

Drawbacks:

  • no checking if piece is in its right place
  • if more than 100 pieces - it starts to lag, because, when picking up a piece, it goes through all subviews until it finds correct piece.

UPDATE

Thanks for updated question.

I managed to get this:

enter image description here

As you can see - jigsaw item is cropped correctly, and it is in square imageView (green color is UIImageView backgroundColor).

So - what I did was:

CGRect rect = CGRectMake(105, 0, 170, 170); //~ location on cat image where second Jigsaw item will be.  UIImage *originalCatImage = [UIImage imageNamed:@"cat.png"];//original cat image  UIImage *jigSawItemMask = [UIImage imageNamed:@"JigsawItemNo2.png"];//second jigsaw item mask (visible in my answer) (same width/height as cat image.)  UIImage *fullJigSawItemImage = [jigSawItemMask maskImage:originalCatImage];//masking - so that from full cat image would be visible second jigsaw item  UIImage *croppedJigSawItemImage = [self fullJigSawItemImage withRect:rect];//cropping so that we would get small image with jigsaw item centered in it. 

For image masking I am using UIImage category function: (but you can probably use your masking function. But I'll post it anyways.)

- (UIImage*) maskImage:(UIImage *)image   {           CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();       UIImage *maskImage = self;      CGImageRef maskImageRef = [maskImage CGImage];       // create a bitmap graphics context the size of the image      CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);        if (mainViewContentContext==NULL)           return NULL;       CGFloat ratio = 0;       ratio = maskImage.size.width/ image.size.width;       if(ratio * image.size.height < maskImage.size.height) {           ratio = maskImage.size.height/ image.size.height;      }        CGRect rect1  = {{0, 0}, {maskImage.size.width, maskImage.size.height}};      CGRect rect2  = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};        CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);      CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);        // Create CGImageRef of the main view bitmap content, and then      // release that bitmap context      CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);      CGContextRelease(mainViewContentContext);       UIImage *theImage = [UIImage imageWithCGImage:newImage];       CGImageRelease(newImage);       // return the image      return theImage; } 

PREVIOUS ANSWER

Can you prepare a mask for each piece?

For example, you have that frame image. Can you cut it in photoshop in 9 separate images, where in each image it would only show corresponding piece. (all the rest - delete).

Example - second piece mask:

enter image description here

Then you use each of these newly created mask images on cat image - each piece will mask all image, but one peace. Thus you will have 9 piece images using 9 different masks.

For larger or different jigsaw frame - again, create separated image masks.

This is a basic solution, but not perfect, as you need to prepare each peace mask separately.

Hope it helps..

like image 77
Guntis Treulands Avatar answered Nov 28 '22 12:11

Guntis Treulands