在目标c中将图像转换为黑白

时间:2014-01-07 22:36:17

标签: ios objective-c

我正在尝试将图像(UIImage *)转换为目标C中的黑白(1bpp)位图(.bmp)。首先,我得到ARGB 32位格式的原始像素数据(每个组件8位)。然后操纵像素数据以获得黑白版本。

我对C#,Java和C ++使用了相同的逻辑,似乎工作正常。但是,对于Objective C(iOS),它没有生成正确的图像。我做错了什么?

以下是我的代码:

- (unsigned int *) convertTo1BPP:(UIImage *)image {

CGContextRef    context = NULL;
CGColorSpaceRef colorSpace;
unsigned int*  bitmapData;
int             bitmapByteCount;
int             bitmapBytesPerRow;


// Create the bitmap context
CGImageRef imageRef = [image CGImage];
// Get image width, height. We'll use the entire image.
unsigned int width = CGImageGetWidth(imageRef);
unsigned int height = CGImageGetHeight(imageRef);
unsigned int bitmapStride =((width +31)/32)*4;

// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow   = (width* 4);
bitmapByteCount     = (bitmapBytesPerRow * height);


// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
bitmapData = malloc( bitmapByteCount );

// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
// kCGImageAlphaPremultipliedFirst
// AAAAAAAARRRRRRRRRGGGGGGGGBBBBBBBB 32 bits per pixel, 8 bits per ARGB component with premultiplied alpha.
context = CGBitmapContextCreate (bitmapData,
                                 width,
                                 height,
                                 8,      // bits per component
                                 bitmapBytesPerRow,
                                 colorSpace,
                                 kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedFirst);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetShouldAntialias(context, NO);


// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

// Now we can get a pointer to the image data associated with the bitmap
// context.
//unsigned char* data = CGBitmapContextGetData (context);
unsigned int* newBitmapData = malloc(((width+31)& ~31)/8 *height);
if (bitmapData != NULL)
{   
    for (unsigned int y = 0; y < height; y++)
    {
        for (unsigned int x = 0; x < width; x++)
        {
            unsigned char mask = 0x80 >> (x & 0x7);

            //Get Pixel data(format 0xAARRGGBB)
            unsigned char rgbPixel = bitmapData[y*width + x];

            //get red color(0x0000AARR & 0xFF => 0x000000RR)
            int red = (unsigned char) (rgbPixel >> 16)& 0xFF;

            //get green color(0x00AARRGG & 0xFF => 0x000000GG)
            int green = (unsigned char) (rgbPixel >> 8)& 0xFF;

            //get blue color(0xAARRGGBB & 0xFF => 0x000000BB)
            int blue = (unsigned char) (rgbPixel >> 0)& 0xFF;

            //calculate brightness
            int brightness = (.299*red + .587*green + .116*blue);

            if(brightness > 128)
            {
                int index = (height-y-1)*bitmapStride + (x/8);
                newBitmapData[index] |= mask;
            }
        }
    }
}

free(bitmapData);
return newBitmapData;

}

0 个答案:

没有答案