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

此代码首先将图像转换为单通道灰度。如果您想在三通道图像上进行抖动,您可以将图像分成三个通道并调用该函数三次(每个通道一次)。

于 2013-07-27T17:59:40.893 回答