4

iOS5 と iOS6 でアプリを開発しました。XCode 5 と iOS7 にアップグレードした後、いくつかの新しいバグに対処する必要があります。

主なものは、カラーマスキングが機能しなくなったことです。まったく同じコードが引き続きコンパイルされ、iOS6 を搭載した電話で動作します。iOS7 では、マスクされた色がまだ残っています。Google で答えを見つけようとしましたが、答えが見つかりませんでした。それは iOS7 のバグですか、それともカラーマスキングを行うためのより良い方法を知っている人はいますか?

コードは次のとおりです。

- (UIImage*) processImage :(UIImage*) image
{
    UIImage *inputImage = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)];
    const float colorMasking[6]={100.0, 255.0, 0.0, 100.0, 100.0, 255.0};
    CGImageRef imageRef = CGImageCreateWithMaskingColors(inputImage.CGImage, colorMasking);
    UIImage* finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return finalImage;
}

最初にiOS6 で動作させるのに役立った、私が見つけたいくつかのStackOverflowの投稿を 次に示します。

4

2 に答える 2

8

CGImageCreateWithMaskingColorsと組み合わせての奇妙な動作に出くわしましたUIImagePNGRepresentation。これは、問題に関連している場合とそうでない場合があります。私はそれを見つけました:

  1. その画像を使用CGImageCreateWithMaskingColorsしてすぐに画像ビューに追加すると、透明度が正しく適用されているように見えます。

  2. しかし、iOS 7 では、次の場合:

    • この画像を から取得し、 usingCGImageCreateWithMaskingColorsを作成します。とNSDataUIImagePNGRepresentation

    • NSDataを使用してその画像をリロードするimageWithDataと、結果の画像には透明度がなくなります。

    これを確認するwriteToFileためNSDataに、保存した画像を Photoshop などのツールで調べると、ファイルに透明度が適用されていないことが確認できます。

    これは iOS 7 でのみ現れます。iOS 6 では問題ありません。

  3. しかし、ステップ 1 で画像を取得して を往復するとdrawInRect、画像を保存してからロードする同じプロセスが正常に機能します。

この次のコードは、問題を示しています。

- (UIImage*) processImage :(UIImage*) inputImage
{
    const float colorMasking[6] = {255.0, 255.0, 255.0, 255.0, 255.0, 255.0};
    CGImageRef imageRef = CGImageCreateWithMaskingColors(inputImage.CGImage, colorMasking);
    UIImage* finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    // If I put this image in an image view, I see the transparency fine.

    self.imageView.image = finalImage;                           // this works

    // But if I save it to disk and the file does _not_ have any transparency

    NSString *documentsPath           = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *pathWithoutTransparency = [documentsPath stringByAppendingPathComponent:@"image-but-no-transparency.png"];
    NSData   *data                    = UIImagePNGRepresentation(finalImage);
    [data writeToFile:pathWithoutTransparency atomically:YES];   // save it so I can check out the file in Photoshop

    // In iOS 7, the following imageview does not honor the transparency

    self.imageView2.image = [UIImage imageWithData:data];        // this does not work in iOS 7

    // but, if I round-trip the original image through `drawInRect` one final time,
    // the transparency works

    UIGraphicsBeginImageContextWithOptions(finalImage.size, NO, 1.0);
    [finalImage drawInRect:CGRectMake(0, 0, finalImage.size.width, finalImage.size.height)];
    UIImage *anotherRendition = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    data = UIImagePNGRepresentation(anotherRendition);
    NSString *pathWithTransparency = [documentsPath stringByAppendingPathComponent:@"image-with-transparancy.png"];
    [data writeToFile:pathWithTransparency atomically:YES];

    // But this image is fine

    self.imageView3.image = [UIImage imageWithContentsOfFile:pathWithTransparency];   // this does work

    return anotherRendition;
}
于 2013-10-01T07:55:38.057 に答える
0

何らかの理由でアルファ チャネルをロードする JPEG をロードしていましたが、マスキング時には機能しません。ここでは、アルファ チャネルを無視して CGImage を再作成します。これを行うためのより良い方法があるかもしれませんが、これは機能します!

- (UIImage *)imageWithChromaKeyMasking {
    const CGFloat colorMasking[6]={255.0,255.0,255.0,255.0,255.0,255.0};
    CGImageRef oldImage = self.CGImage;
    CGBitmapInfo oldInfo = CGImageGetBitmapInfo(oldImage);
    CGBitmapInfo newInfo = (oldInfo & (UINT32_MAX ^ kCGBitmapAlphaInfoMask)) | kCGImageAlphaNoneSkipLast;
    CGDataProviderRef provider = CGImageGetDataProvider(oldImage);
    CGImageRef newImage = CGImageCreate(self.size.width, self.size.height, CGImageGetBitsPerComponent(oldImage), CGImageGetBitsPerPixel(oldImage), CGImageGetBytesPerRow(oldImage), CGImageGetColorSpace(oldImage), newInfo, provider, NULL, false, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider); provider = NULL;
    CGImageRef im = CGImageCreateWithMaskingColors(newImage, colorMasking);
    UIImage *ret = [UIImage imageWithCGImage:im];
    CGImageRelease(im);
    return ret;
}
于 2014-10-28T22:40:07.637 に答える