6

Am developing jigsaw puzzle for iphone.

Here using the masking technique I have cropped the image into 9 peices. See the image below.

After cropping some portion of image is missing due to masking. I knew this is coz of loading those cropped images in square uiimageview.

My question is how to make it as complete cropped image without losing any portion of image and how to fit these pieces correctly to match with original one.

enter image description here

mkobit
  • 43,979
  • 12
  • 156
  • 150
nik
  • 2,289
  • 6
  • 37
  • 60
  • 1
    http://stackoverflow.com/questions/5880597/custom-image-mask-in-ios – Nayan Chauhan Oct 05 '12 at 13:17
  • think this is not related to my question, I have already cropped by masking the image. My question is how to crop by masking without loosing the image portions. – nik Oct 05 '12 at 13:20
  • can u tell me how to crop images like that.i am currently stuck on that part. – Steve Dec 13 '12 at 13:20
  • @nik:can you help me how you crop these images i am also stuck on that any your code sample will be very helpful to me.Thanks. – M.B Dec 17 '12 at 05:51
  • and write your own logic for image pieces misalignment & game completion detection. – nik Dec 17 '12 at 08:46
  • @nik: Thanks thats a great idea you give me.if you give any small sample that very easy to understand masking images.but if cant its ok. – M.B Dec 20 '12 at 06:18
  • @nik: is that 9 peace for masking is any color? – M.B Dec 20 '12 at 06:20
  • @nik: i think i will not use bezier curve for irregular shape according your logic? – M.B Dec 20 '12 at 06:24
  • yes you dont need bezier curve and in that 9 peaces color doesnt matter – nik Dec 20 '12 at 09:30
  • @nik:can you add me on skype my skype id is mohit.bisht23 – M.B Dec 20 '12 at 09:36
  • @nik: Hi, I'm also developing jigsaw puzzle for iPhone. I've tried code mentioned here http://mobiledevelopertips.com/cocoa/how-to-mask-an-image.html but no luck. It would be great if you could share the piece of code you have used. I want to make 3x3 grid for the jigsaw. Thanks in advance. – Kavya Indi Jan 04 '13 at 09:35

3 Answers3

3

Build a set of masks corresponding to to each puzzle piece. Each mask should be the size of the original image and all black except for a white area with the position and shape of the puzzle piece. Also, maintain a bounding rectangle for each piece (a rectangle that minimally contains the piece in the mask image).

The way to not lose any of the original image is to arrange the masks (and the corresponding bounding rects) as a partition over the image.

Here's a link to some code that demonstrates how to apply a mask. Once the mask is applied, crop the masked image to the bounding rectangle using code like here and elsewhere.

Community
  • 1
  • 1
danh
  • 62,181
  • 10
  • 95
  • 136
  • Thanks for reply. I owuld like you to see this link http://stackoverflow.com/questions/10810798/cropping-image-with-transparency-in-iphone I have just followed the steps which mentioned here. as you said above the peices which i using is exactly matching with original image. – nik Oct 05 '12 at 13:42
  • the dimension of each pieces will vary coz here we are masking with irregular shaped images. So expecting something else which matching my way of implementation – nik Oct 05 '12 at 13:45
  • Just to be sure you understand my point: don't worry about cropping for a minute, just consider a 12 piece puzzle as 12 images, all of them _the_exact_same_size_ as the original image. Each is mostly transparent, with just one opaque region corresponding to the piece. That's your puzzle. Cropping those to only include a rectangle containing the piece is an optional step, just to give more convenient sizes. – danh Oct 05 '12 at 14:06
2

I am also thinking that divided original image with masking but it might be bad idea for us and also complicated to manage it. So For user who is beginner for jigsaw puzzle then This is the best question/answer and also you can get source code of jigsaw puzzle game from git.

Please hats off this man (@"Guntis Treulands") who solve your problem. I know this should be not an answer but should be comment but If I will put it as comment then may be user who have problem with jigsaw puzzle he/she can not find it easily so. I am putting it as an answer.

Community
  • 1
  • 1
iPatel
  • 46,010
  • 16
  • 115
  • 137
1
//Create our colorspaces
imageColorSpace = CGColorSpaceCreateDeviceRGB();
maskColorSpace = CGColorSpaceCreateDeviceGray();
provider=CGDataProviderCreateWithCFData((__bridge CFDataRef)self.puzzleData);
image=CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);

//Resize the puzzle image
context = CGBitmapContextCreate(NULL, kPuzzleSize, kPuzzleSize, 8, 0, imageColorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, kPuzzleSize, kPuzzleSize), image);
CGImageRelease(image);
image = CGBitmapContextCreateImage(context);
CGContextRelease(context);

//Create the image view with the puzzle image
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPuzzleSize, kPuzzleSize)];
[self.imageView setImage:[UIImage imageWithCGImage:image]];

//Create the puzzle pieces (note that pieces are rotated to the puzzle orientation in order to minimize the number of graphic operations when creating the puzzle images)
for(i = 0; i < appDelegate().puzzleSize * appDelegate().puzzleSize; ++i)
{
    //Recreate the piece view
    [pieces[i] removeFromSuperview];
    pieces[i] = [[CJPieceView alloc] initWithFrame:CGRectMake(0, 0, kPieceSize, kPieceSize) index:i];
    [pieces[i] setTag:-1];

    //Load puzzle piece mask image
    UIImage *maskimage=[self.arrmaskImages objectAtIndex:i];
    NSData *dataMaskImage=UIImagePNGRepresentation(maskimage);

    provider=CGDataProviderCreateWithCFData((__bridge CFDataRef)dataMaskImage);
    tile = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);
    mask = CGImageCreateCopyWithColorSpace(tile, maskColorSpace);
    CGImageRelease(tile);

    context = CGBitmapContextCreate(NULL, kPieceSize / kPieceShadowFactor, kPieceSize / kPieceShadowFactor, 8, 0, imageColorSpace, kCGImageAlphaPremultipliedFirst);
    CGContextClipToMask(context, CGRectMake(0, 0, kPieceSize / kPieceShadowFactor, kPieceSize / kPieceShadowFactor), mask);
    CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
    CGContextFillRect(context, CGRectMake(0, 0, kPieceSize / kPieceShadowFactor, kPieceSize / kPieceShadowFactor));
    shadow = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPieceSize, kPieceSize)];
    [imageView setImage:[UIImage imageWithCGImage:shadow]];
    [imageView setAlpha:kPieceShadowOpacity];
    [imageView setUserInteractionEnabled:NO];
    [pieces[i] addSubview:imageView];
    CGImageRelease(shadow);

    //Create image view with piece image and add it to the piece view
    context = CGBitmapContextCreate(NULL, kPieceSize, kPieceSize, 8, 0, imageColorSpace, kCGImageAlphaPremultipliedFirst);
    CGRect rectPiece= CGRectMake(fmodf(i, appDelegate().puzzleSize) * kPieceDistance, (floorf(i / appDelegate().puzzleSize)) * kPieceDistance, kPieceSize, kPieceSize);
    [self.arrlocations addObject:[NSValue valueWithCGRect:rectPiece]];
    CGContextTranslateCTM(context, (kPieceSize - kPieceDistance) / 2 - fmodf(i, appDelegate().puzzleSize) * kPieceDistance, (kPieceSize - kPieceDistance) / 2 - (appDelegate().puzzleSize - 1 - floorf(i / appDelegate().puzzleSize)) * kPieceDistance);        
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
    subImage = CGBitmapContextCreateImage(context);     
    CGContextRelease(context); 
    tile = CGImageCreateWithMask(subImage, mask);
    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPieceSize, kPieceSize)];
    [imageView setImage:[UIImage imageWithCGImage:tile]];
    [imageView setUserInteractionEnabled:NO];
    [pieces[i] addSubview:imageView];
    CGImageRelease(tile);
    CGImageRelease(subImage);
    DLog(@"%f", pieces[i].frame.size.width);
    pieces[i].transform=CGAffineTransformScale(CGAffineTransformIdentity, kTransformScale, kTransformScale);
    DLog(@"%f %f",kTransformScale, pieces[i].frame.size.width);
    //Release puzzle piece mask;
    CGImageRelease(mask);

}

//Clean up
CGColorSpaceRelease(maskColorSpace);
CGColorSpaceRelease(imageColorSpace);
CGImageRelease(image);
coder1010
  • 412
  • 5
  • 15