2

私は画像編集プログラムを書いていますが、任意の 24 ビット RGB 画像 (CoreGraphics などでロードするように注意しました) を 3 ビット カラー チャネルの画像にディザリングして表示する機能が必要です。マトリックスなどを設定しましたが、画像に適用される単純なパターン以外に、以下のコードから結果が得られません。

- (CGImageRef) ditherImageTo16Colours:(CGImageRef)image withDitheringMatrixType:(SQUBayerDitheringMatrix) matrix {
    if(image == NULL) {
        NSLog(@"Image is NULL!");
        return NULL;
    }

    unsigned int imageWidth = CGImageGetWidth(image);
    unsigned int imageHeight = CGImageGetHeight(image);

    NSLog(@"Image size: %u x %u", imageWidth, imageHeight);

    CGContextRef context = CGBitmapContextCreate(NULL, 
                                                 imageWidth, 
                                                 imageHeight, 
                                                 8, 
                                                 4 * (imageWidth), 
                                                 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), 
                                                 kCGImageAlphaNoneSkipLast);

    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image); // draw it
    CGImageRelease(image); // get rid of the image, we don't want it anymore.


    unsigned char *imageData = CGBitmapContextGetData(context);

    unsigned char ditheringModulusType[0x04] = {0x02, 0x03, 0x04, 0x08};
    unsigned char ditheringModulus = ditheringModulusType[matrix];

    unsigned int red;
    unsigned int green;
    unsigned int blue;

    uint32_t *memoryBuffer;
    memoryBuffer = (uint32_t *) malloc((imageHeight * imageWidth) * 4);

    unsigned int thresholds[0x03] = {256/8, 256/8, 256/8};

    for(int y = 0; y < imageHeight; y++) {
        for(int x = 0; x < imageWidth; x++) {
            // fetch the colour components, add the dither value to them
            red = (imageData[((y * imageWidth) * 4) + (x << 0x02)]);
            green = (imageData[((y * imageWidth) * 4) + (x << 0x02) + 1]);
            blue = (imageData[((y * imageWidth) * 4) + (x << 0x02) + 2]);

            if(red > 36 && red < 238) {
                red += SQUBayer117_matrix[x % ditheringModulus][y % ditheringModulus];
            } if(green > 36 && green < 238) {
                green += SQUBayer117_matrix[x % ditheringModulus][y % ditheringModulus];
            } if(blue > 36 && blue < 238) {
                blue += SQUBayer117_matrix[x % ditheringModulus][y % ditheringModulus];
            }

//            memoryBuffer[(y * imageWidth) + x] = (0xFF0000 + ((x >> 0x1) << 0x08) + (y >> 2));
            memoryBuffer[(y * imageWidth) + x] = find_closest_palette_colour(((red & 0xFF) << 0x10) | ((green & 0xFF) << 0x08) | (blue & 0xFF));
        }
    }

    //CGContextRelease(context);
    context = CGBitmapContextCreate(memoryBuffer, 
                                    imageWidth, 
                                    imageHeight, 
                                    8, 
                                    4 * (imageWidth), 
                                    CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), 
                                    kCGImageAlphaNoneSkipLast);

    NSLog(@"Created context from buffer: %@", context);

    CGImageRef result = CGBitmapContextCreateImage(context);
    return result;
}

find_closest_palette_colourテストのために今すぐ元の色を返す以外に何もしないことに注意してください。

ウィキペディアからサンプルの疑似コードを実装しようとしていますが、今のところ何も得られません。

これを修正する方法について手がかりを得た人はいますか?

4

1 に答える 1

0

ここで提供したコードを使用してください: https://stackoverflow.com/a/17900812/342646

このコードは、最初に画像を単一チャネルのグレースケールに変換します。3 チャンネルの画像でディザリングを実行する場合は、画像を 3 つのチャンネルに分割し、関数を 3 回 (チャンネルごとに 1 回) 呼び出すだけです。

于 2013-07-27T17:59:40.893 に答える