在iPhone中以透明的方式裁剪图片

时间:2021-09-07 21:24:08

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;
}

在iPhone中以透明的方式裁剪图片

+

+

在iPhone中以透明的方式裁剪图片

=

=

This is final result i got after masking.

这是经过掩蔽后得到的最终结果。

在iPhone中以透明的方式裁剪图片

now i would like to crop image in piece like 在iPhone中以透明的方式裁剪图片 and 在iPhone中以透明的方式裁剪图片 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

我使用这一行代码作为Guntis Treulands的建议

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:@"cat@2x.png"];
            UIImage *frmImg = [UIImage imageNamed:[NSString stringWithFormat:@"%d@2x.png",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 cat@2x.png.

orgImg是原始的cat图像,frmImg框架用于保存单个片段,在photoshop中蒙面,cropImg是原始cat@2x.png的106x106裁剪图像。

my function for cropping is as following

我的裁剪功能如下。

- (UIImage *) cropImage:(UIImage*)originalImage withRect:(CGRect)rect { 
    return [UIImage imageWithCGImage:CGImageCreateWithImageInRect([originalImage CGImage], rect)]; 
}

1 个解决方案

#1


16  

UPDATE 2

更新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
  • 每一件衣服都可以通过轻击或两根手指(就像真正的一件一样)来旋转——但一旦被释放,它就会突然折断到90/180/270/360度
  • 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.
  • 如果超过100块,它就会开始延迟,因为当拾取一块时,它会遍历所有子视图,直到找到正确的那块。

UPDATE

更新

Thanks for updated question.

谢谢你更新的问题。

I managed to get this:

我设法弄到了这个:

在iPhone中以透明的方式裁剪图片

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

您可以看到- jigsaw项目被正确裁剪,它是在square imageView(绿色是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类别函数:(但是你可能可以使用你的掩蔽函数。但我还是会发布的。

- (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).

例如,你有那个帧图像。你能否在photoshop中把它分割成9张独立的图片,在每张图片中它只显示相应的部分。(全部删除)。

Example - second piece mask:

例子-第二件面具:

在iPhone中以透明的方式裁剪图片

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.

然后你使用每一个新创建的蒙版图像在猫的图像上-每一块将掩盖所有图像,但一个和平。因此,你将有9张图片使用9个不同的面具。

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

对于较大或不同的jigsaw框架——同样,创建独立的图像遮罩。

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

这是一个基本的解决方案,但并不完美,因为您需要分别准备每个和平面具。

Hope it helps..

希望它能帮助. .

#1


16  

UPDATE 2

更新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
  • 每一件衣服都可以通过轻击或两根手指(就像真正的一件一样)来旋转——但一旦被释放,它就会突然折断到90/180/270/360度
  • 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.
  • 如果超过100块,它就会开始延迟,因为当拾取一块时,它会遍历所有子视图,直到找到正确的那块。

UPDATE

更新

Thanks for updated question.

谢谢你更新的问题。

I managed to get this:

我设法弄到了这个:

在iPhone中以透明的方式裁剪图片

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

您可以看到- jigsaw项目被正确裁剪,它是在square imageView(绿色是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类别函数:(但是你可能可以使用你的掩蔽函数。但我还是会发布的。

- (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).

例如,你有那个帧图像。你能否在photoshop中把它分割成9张独立的图片,在每张图片中它只显示相应的部分。(全部删除)。

Example - second piece mask:

例子-第二件面具:

在iPhone中以透明的方式裁剪图片

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.

然后你使用每一个新创建的蒙版图像在猫的图像上-每一块将掩盖所有图像,但一个和平。因此,你将有9张图片使用9个不同的面具。

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

对于较大或不同的jigsaw框架——同样,创建独立的图像遮罩。

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

这是一个基本的解决方案,但并不完美,因为您需要分别准备每个和平面具。

Hope it helps..

希望它能帮助. .