23

私はマスキング用の 2 つの画像があるジグソー タイプのゲームに取り組んでいます。マスキング用にこのコードを実装しました。

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

ここに画像の説明を入力

+

ここに画像の説明を入力

=

これがマスキング後の最終結果です。

ここに画像の説明を入力

今、私はパラメトリックに画像を切り取りたいと思ってここに画像の説明を入力ここに画像の説明を入力ます(透明度によって画像を切り抜きます)。

このシナリオでそのようなコードまたはアイデアを実装した人がいる場合は、共有してください。

ありがとう。

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 は元の猫の画像、frmImg は個々のピースを保持するためのフレームで、Photoshop でマスクされています。cropImg は元の cat@2x.png の 106x106 のトリミングされた画像です。

トリミングのための私の機能は次のとおりです

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

1 に答える 1

17

更新 2

ジグソー パズルを作成するためのより良い方法を見つけることに非常に興味を持ったので、2 週間の週末を費やしてジグソー パズルのデモ プロジェクトを作成しました。

を含む:

  • 列/行数を指定すると、必要なパズルのピースが正しい幅/高さで生成されます。列/行が多いほど、幅/高さとアウトライン/インライン パズル フォームが小さくなります。
  • 毎回ランダムな面を生成する
  • 発射の開始時にピースをランダムに配置/回転できます
  • 各ピースはタップまたは 2 本の指 (本物のピースのように) で回転できますが、離すと 90/180/270/360 度にスナップします
  • 「タッチ可能な形状」の境界に触れると、各ピースを動かすことができます (これはほとんど同じ表示パズル形状ですが、インライン形状はありません)。

欠点:

  • ピースが正しい場所にあるかどうかのチェックなし
  • 100 ピースを超えると、ピースを拾うときに正しいピースが見つかるまですべてのサブビューを通過するため、ラグが発生し始めます。

アップデート

更新された質問をありがとう。

私はこれを得ることができました:

ここに画像の説明を入力

ご覧のとおり、ジグソー アイテムは正しくトリミングされており、正方形の imageView になっています(緑色は UIImageView backgroundColor です)。

だから - 私がしたことは:

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.

画像のマスキングには、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;
}

前の回答

1枚ずつマスクを用意してもらえますか?

たとえば、そのフレーム画像があります。Photoshop で 9 つの個別の画像にカットできますか。各画像には、対応する部分のみが表示されます。(残りすべて - 削除)。

例 - 2 枚目のマスク:

ここに画像の説明を入力

次に、これらの新しく作成されたマスク画像を猫の画像に使用します。各ピースはすべての画像をマスクしますが、平和は 1 つです。したがって、9 つの異なるマスクを使用して 9 枚の画像が作成されます。

より大きな、または異なるジグソー フレームの場合 - ここでも、個別のイメージ マスクを作成します。

これは基本的な解決策ですが、各ピースマスクを個別に準備する必要があるため、完全ではありません.

それが役に立てば幸い..

于 2012-06-01T07:16:10.307 に答える