【问题标题】:Implementing Ordered Dithering (24 bit RGB to 3 bit per channel RGB)实现有序抖动(24 位 RGB 到每通道 3 位 RGB)
【发布时间】:2012-09-26 13:20:43
【问题描述】:

我正在编写一个图像编辑程序,我需要将任意 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 除了立即返回原始颜色进行测试之外,并没有做任何事情。

我正在尝试实现来自 Wikipedia 的示例伪代码,但我现在并没有真正从中得到任何东西。

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: image-processing core-graphics dithering


    【解决方案1】:

    使用我在这里提供的代码:https://stackoverflow.com/a/17900812/342646

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

    【讨论】:

      猜你喜欢
      • 2016-07-05
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      • 2012-07-17
      • 2011-02-05
      • 1970-01-01
      • 2012-10-31
      相关资源
      最近更新 更多