2

Apple の iOS に最適化された BGRA PNG 形式 ( OptimizedPNGを使用して取得したもの) の PNG があり、CoreGraphics に画像のアルファ コンポーネントを無視しないように指示する方法でそれらを描画したいと考えています。私はに描いていCGContextRefますdrawRect:

編集:レンダリングされた画像は、完全に透明であるべき場所が黒く表示されます(他のランダムなアーティファクトがある場合があります)。不透明な領域は正常にレンダリングされます。 これCGImageAlphaInfoは、OptimizedPNG による画像の保存方法に問題があることを示しているようです。これはあるべきだと思います。kCGImageAlphaNoneSkipLastkCGImageAlphaPremultipliedLast

PNG チャンクが間違っている可能性がありますが、IHDR に問題は見られず、CgBI チャンクについてはほとんど見つかりません。

これは、OptimizedPNG がカラー データを保存する方法です。

// IDAT
int size = width*height*4;
unsigned char *buffer = malloc(size);
CGContextRef context = CGBitmapContextCreate(buffer, width, height, 8, width*4, CGImageGetColorSpace(originalImage.CGImage), kCGImageAlphaPremultipliedLast);
CGRect rect = CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height);
CGContextDrawImage(context, rect, originalImage.CGImage);
CGContextRelease(context);

int size_line = 1 + width*4;
int size_in = height*size_line;
unsigned char *buffer_in = malloc(size_in);
for(int y = 0; y < height; ++y){
    unsigned char *src = &buffer[y*width*4];
    unsigned char *dst = &buffer_in[y*size_line];
    *dst++ = 1;
    unsigned char r = 0, g = 0, b = 0, a = 0;
    for(int x = 0; x < width; ++x){
        dst[0] = src[2] - b;
        dst[1] = src[1] - g;
        dst[2] = src[0] - r;
        dst[3] = src[3] - a;
        r = src[0], g = src[1], b = src[2], a = src[3];
        src += 4;
        dst += 4;
    }
}
4

2 に答える 2

1

PNG にアルファ チャネルがないようです。

OptimizedPNG にバグがあるのか​​もしれません。知らない。を使ってみてくださいUIImagePNGRepresentation

元の画像にアルファ チャンネルがなかった可能性があります。プレビューで確認できます ([ツール] > [インスペクターを表示] を選択し、[詳細情報] > [一般] で [アルファあり] を探します)。

また、ビューopaqueが NO であり、それbackgroundColorがであることを確認してくださいclearColor。システムによって作成されたコンテキストに描画していない場合は、アルファ チャネルを使用してコンテキストを作成していることを確認してください。

あなたのコメントに基づいて、iOS 5.1.1 を実行している iPad 3 でこのコードをテストしました。

UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://upload.wikimedia.org/wikipedia/commons/f/fb/Wikisource-logo.png"]]];
NSData *data = UIImagePNGRepresentation(image);
NSURL *documentDirectoryURL = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject;
NSURL *url = [documentDirectoryURL URLByAppendingPathComponent:@"test.png"];
[data writeToURL:url atomically:YES];

test.png次に、Xcode オーガナイザーを使用してデバイスからコピーしました。ファイルをプレビューで開いて確認しました。まだアルファチャンネルがありました。

それでも問題が解決しない場合は、画像の操作に関連するすべてのコードを表示する必要があります。何かが抜け落ちているからです。質問を編集して、詳細とコードを含めます。

于 2012-08-16T04:09:43.440 に答える
0

あなたが私たちに言ったことから、透明レイヤーを使用する理由はありません. 透過レイヤーは、2 つ以上のオブジェクトを組み合わせて、1 つのオブジェクトとして扱われる合成グラフィックを生成するために使用されます。これは、個々のオブジェクトではなく複合オブジェクトに効果を適用する場合に便利です。非常に一般的なケースは、複数のオブジェクトの合成に影を適用することです。

を使用CGContextDrawImage()するだけで、アルファ チャネルを考慮して画像がグラフィックス コンテキストに合成されます。新しい画像がグラフィック コンテンツに既に存在するコンテンツにどのように合成されるかは、グラフィック コンテンツに設定されたブレンド モードによって異なります。でブレンドモードを設定しますCGContextSetBlendMode()。詳細な説明は、Quartz 2D Programming Guide: Bitmaps Images and Masks にあります。参考文献からわかるように、画像を合成する方法には多くのオプションがありますが、私はあなたが念頭に置いていたと推測するかもしれませkCGBlendModeMultiplykCGBlendModeNormal. デフォルトはkCGBlendModeNormalであることに注意してください。これは、アルファ値を考慮して、現在コンテキストにあるものの上にソース イメージ サンプルをペイントするだけです。

于 2012-08-16T04:09:30.393 に答える