2013-10-01 205 views
1

这种情况下,iOS - 如何将png图像转换为4位位图灰度?

我想使用iOS6 +将PNG图像(或JPEG)转换为4位位图灰度图像,即4位位图只需要支持16灰度颜色。

我该怎么办?

在此先感谢。

+0

http://stackoverflow.com/questions/1298867/convert-image-to-grayscale – Spynet

+0

谢谢,我会检查它,代码让我有些事情要做。 –

回答

0

你可以将它转换为8位灰度图像(见Convert UIImage to 8 bits,或见the link that Spynet shared包括其他排列),但我无法适应,要创建4位灰度位图(CGBitmapContextCreate抱怨说,它不是一个有效的参数组合)。它看起来应该是理论上可行的(有012位的,pixel format types下列出的4位格式),但我无法让它工作这种技术。

+0

感谢您的回答,我会检查它。 –

0

我找到了将图像转换为4位灰度的解决方案,代码如下。

-(UIImage *)grayscaleImageAt4Bits:(UIImage *)_image 
{ 
    CGImageRef imageRef = [_image CGImage]; 
    int width = CGImageGetWidth(imageRef); 
    int height = CGImageGetHeight(imageRef); 
    NSInteger _bitsPerComponent = 8; 
    NSInteger _bytesPerPixel = 1; 
    NSInteger _bytesPerRow  = _bytesPerPixel * width; 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 
    uint8_t *sourceData = malloc(height * width * _bytesPerPixel); 
    CGContextRef context = CGBitmapContextCreate(sourceData, 
               width, 
               height, 
               _bitsPerComponent, 
               _bytesPerRow, 
               colorSpace, 
               kCGImageAlphaNone); 
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 

    const int _redIndex = 0; 
    const int _greenIndex = 1; 
    const int _blueIndex = 2; 
    int _byteIndex = 0; 
    int _bitIndex = 0; 
    uint8_t *_newImageBits = malloc(height * width * _bytesPerPixel/2); 
    for(int j=0;j<height;j++) 
    { 
     for(int k=0;k<width;k++) 
     { 
      UInt8 _perPixel = _newImageBits[_byteIndex]; 
      UInt8 *rgbPixel = (UInt8 *) &sourceData[j * width + k]; 
      int _red = rgbPixel[_redIndex]; 
      int _green = rgbPixel[_greenIndex]; 
      int _blue = rgbPixel[_blueIndex]; 
      int _pixelGrayValue = (_green + _red + _blue)/16; 
      UInt8 _pixelByte = (UInt8)_pixelGrayValue; 
      _perPixel |= (_pixelByte<<4); 
      _newImageBits[_byteIndex] = _perPixel; 
      _bitIndex += 4; 
      if(_bitIndex > 7) 
      { 
       _byteIndex++; 
       _bitIndex = 0; 
      } 
     } 
    } 
    free(sourceData); 
    //Direct fetch Bytes of 4-Bits, then you can use this Bytes (sourceData) to do something. 
    sourceData = _newImageBits; 
    CGImageRef cgImage = CGBitmapContextCreateImage(context); 
    UIImage *_grayImage = [UIImage imageWithCGImage:cgImage]; 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 
    //Convert to NSData type, then you can use this NSData (_sourceImageData) to do something. 
    NSData *_sourceImageData = [NSData dataWithBytes:sourceData length:(width * height * _bytesPerPixel)]; 
    free(sourceData); 
    return _grayImage; 
} 

而iOS只支持至少8位颜色显示,所以4位数据只传输到openGL的纹理使用。

+0

iOS 8,现在给出一个警告:'将枚举类型'enum CGImageAlphaInfo'隐式转换为不同的枚举类型'CGBitmapInfo'(又名'enum CGBitmapInfo')' –

相关问题