1

次のようなPNGファイルを読みたい:

a)色空間の調整やアルファの事前乗算を行わに、ファイルの生のビットマップデータにアクセスします。

b)そのビットマップに基づいて、ウィンドウ内の画像にビットスライス(画像全体のR、G、B、またはAの任意の1ビット)を表示します。ビットマップがある場合、適切なビットを見つけることができますが、それらを画面に表示するために何を詰め込むことができますか?

c)ビットプレーンを変更した後、調整なしで新しいPNGファイルを書き込みます。

これは特定の画像専用です。PNGには、単にRGBA-32以外のデータは含まれていません。

ここでいくつかの同様の質問を読んだことから、ファイルの読み取り/書き込みのNSBitmapImageRepを疑っており、画面上の部分のNSViewを描画しています。これは正しいですか?

4

2 に答える 2

1

1.)NSBitmapImageRepの-bitmapDataを使用して、生のピクセルデータを取得できます。残念ながら、CG(NSBitmapImageRepのバックエンド)はネイティブの事前乗算をサポートしていないため、自分で事前乗算を解除する必要があります。これで使用される色空間は、ファイルに存在するものと同じになります。画像データの事前乗算を解除する方法は次のとおりです。

NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:data];
    NSInteger width = [imageRep pixelsWide];
    NSInteger height = [imageRep pixelsHigh];

    unsigned char *bytes = [imageRep bitmapData];
    for (NSUInteger y = 0; y < width * height * 4; y += 4) { // bgra little endian + alpha first
        uint8_t a, r, g, b;

        if (imageRep.bitmapFormat & NSAlphaFirstBitmapFormat) {
            a = bytes[y];
            r = bytes[y+1];
            g = bytes[y+2];
            b = bytes[y+3];
        } else {
            r = bytes[y+0];
            g = bytes[y+1];
            b = bytes[y+2];
            a = bytes[y+3];
        }

        // unpremultiply alpha if there is any
        if (a > 0) {
            if (!(imageRep.bitmapFormat & NSAlphaNonpremultipliedBitmapFormat)) {
                float factor = 255.0f/a;
                b *= factor;
                g *= factor;
                r *= factor;
            }
        } else {
            b = 0;
            g = 0;
            r = 0;
        }
        bytes[y]=a; // for argb
        bytes[y+1]=r;
        bytes[y+2]=g;
        bytes[y+3]=b;
    }

2.)これを行う簡単な方法を考えることができませんでした。生の画像データをループし、値に基づいて新しい画像を生成する独自の画像描画方法を作成できます。それを開始する方法については、上記を参照してください。

3.)生データの場所からCGImageを取得する方法は次のとおりです(ネイティブのCG関数を使用してpngをファイルに書き込むか、CGで不快な場合はNSBitmapImageRepに変換できます)

static CGImageRef cgImageFrom(NSData *data, uint16_t width, uint16_t height) {
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaFirst;

CGImageRef cgImage = CGImageCreate(width, height, 8, 32, 4 * width, colorSpace, bitmapInfo, provider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return cgImage;
}

+ dataWithBytes:lengthを使用して、生データオブジェクトからNSDataオブジェクトを作成できます。

于 2011-11-04T20:56:00.913 に答える
0

私はこの分野で働いたことがありませんが、これにはImageIOを使用できる可能性があります。

于 2011-11-05T02:01:20.373 に答える