2012-09-26 5 views
2

저는 이미지 편집 프로그램을 작성하고 있으며, 임의의 24 비트 RGB 이미지를 디더링하는 기능이 필요합니다 (CoreGraphics 그런 다음 3 비트 색상 채널이있는 이미지에 표시 한 다음 표시합니다. 내 매트릭스를 설정하고 같은,하지만 난 이미지에 적용되는 간단한 패턴 외에 아래의 코드에서 어떤 결과를 가지고 적이 없다했습니다 반환 외에 아무것도하지 않는Ordered Dithering 구현 (채널당 24 비트 RGB에서 3 비트 RGB)

- (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의 예제 의사 코드를 구현하려고하는데, 지금은 그다지 아무것도 얻지 못한다.

누구나이 문제를 해결하는 방법에 대한 단서가 있습니까?

답변

0

내가 여기에 제공 한 코드를 사용 https://stackoverflow.com/a/17900812/342646

이 코드는 먼저 단일 채널 그레이 스케일로 이미지를 변환합니다. 디더링을 3 채널 이미지에서 수행하려는 경우 이미지를 3 개의 채널로 분할하고 해당 기능을 세 번 (채널당 한 번) 호출 할 수 있습니다.