2

グレースケール UIImage マスクを UIImage に適用する (標準) コードを大量に借用しました。

- (void) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef imageRef = image.CGImage;  // main UIImage
    CGImageRef maskRef = maskImage.CGImage;  // grayscale UIImage mask

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                    CGImageGetHeight(maskRef),
                                    CGImageGetBitsPerComponent(maskRef),
                                    CGImageGetBitsPerPixel(maskRef),
                                    CGImageGetBytesPerRow(maskRef),
                                    CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask(imageRef, mask);

    maskedImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(mask);
    CGImageRelease(masked);

    imageView.image = maskedImage;

}

次に、imageView.image をファイルに保存します。このコードは、iOS 6 および 6.1 ではうまく機能します。保存された画像には、マスクが適用されたメインの UIImage が含まれています。ただし、このコードは iOS 7 (iPhone) では同じようには機能しないことに気付きました。iOS 7 では、保存されたイメージには、マスクが適用されていないメインの UIImage のみが含まれます。問題が CGImageCreateWithMask() メソッドにあるのか、他の場所にあるのかはわかりません。

任意の洞察をいただければ幸いです。よろしくお願いします。

4

3 に答える 3

6

私も自分のアプリでこの問題を見つけ、次のコードで解決しました。

- (UIImage*)image:(UIImage*)image withMask:(UIImage*)maskImage
{
    CGImageRef maskRef = maskImage.CGImage;
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                    CGImageGetHeight(maskRef),
                                    CGImageGetBitsPerComponent(maskRef),
                                    CGImageGetBitsPerPixel(maskRef),
                                    CGImageGetBytesPerRow(maskRef),
                                    CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef maskedImageRef = CGImageCreateWithMask([handledImage CGImage], mask);
    CGImageRelease(mask);

    // Under iOS 7, UIImage with mask no longer applied mask when saving it.
    // We draw the image to context and obtain image from context to get the image applied mask
    CGContextRef context = CGBitmapContextCreate(nil,
                                                 CGImageGetWidth(maskedImageRef),
                                                 CGImageGetHeight(maskedImageRef),
                                                 CGImageGetBitsPerComponent(maskedImageRef),
                                                 CGImageGetBytesPerRow(maskedImageRef),
                                                 CGImageGetColorSpace(maskedImageRef),
                                                 CGImageGetBitmapInfo(maskedImageRef));

    CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(maskedImageRef), CGImageGetHeight(maskedImageRef));
    CGContextDrawImage(context, imageRect, maskedImageRef);
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    UIImage *maskedImage = [UIImage imageWithCGImage:imageRef];

    CFRelease(imageRef);
    CGContextRelease(context);
    CGImageRelease(maskedImageRef);

    return maskedImage;
}
于 2013-09-24T09:48:45.573 に答える
6

上記のコードは、問題にアプローチする方法(コンテキストを描画する)の良いアイデアを提供しますが、私にはうまくいきませんでした。以下のコードは、IOS 7 と以前のバージョン (IOS 6.x) の両方で機能します。

+(UIImage*)maskImageExt:(UIImage *)image withMask:(UIImage *)maskImage {
    CGImageRef maskRef = maskImage.CGImage;
    CGImageRef imageRef = image.CGImage;

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, true);

    CGImageRef maskImageRef = CGImageCreateWithMask([image CGImage], mask);

    CGContextRef context = CGBitmapContextCreate(nil,
                                                 CGImageGetWidth(imageRef),
                                                 CGImageGetHeight(imageRef),
                                                 CGImageGetBitsPerComponent(imageRef),
                                                 CGImageGetBytesPerRow(imageRef),
                                                 CGImageGetColorSpace(imageRef),
                                                 CGImageGetBitmapInfo(imageRef));
    CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
    CGContextDrawImage(context, imageRect, maskImageRef);
    CGImageRef maskedImageRef = CGBitmapContextCreateImage(context);
    UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];

    CGImageRelease(mask);
    CGContextRelease(context);
    CGImageRelease(maskedImageRef);

    return maskedImage;
}
于 2013-11-21T19:00:24.103 に答える