【发布时间】:2013-10-07 01:54:28
【问题描述】:
这种情况,
我想使用 iOS6+ 将 PNG 图像(或 JPEG)转换为 4-Bits Bitmap 灰度图像,该 4-Bits 位图只需要支持 16 种灰度。
我该怎么办?
提前致谢。
【问题讨论】:
-
谢谢,我会检查一下代码是否能让我做一些有意义的事情。
这种情况,
我想使用 iOS6+ 将 PNG 图像(或 JPEG)转换为 4-Bits Bitmap 灰度图像,该 4-Bits 位图只需要支持 16 种灰度。
我该怎么办?
提前致谢。
【问题讨论】:
我找到了将图像转换为 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的纹理中使用。
【讨论】:
implicit conversion from enumeration type 'enum CGImageAlphaInfo' to different enumeration type 'CGBitmapInfo' (aka 'enum CGBitmapInfo')
您可以将其转换为 8 位灰度图像(参见 Convert UIImage to 8 bits,或参见包含其他排列的 the link that Spynet shared),但我无法适应它来创建 4 位灰度位图(CGBitmapContextCreate 抱怨它不是一个有效的参数组合)。似乎理论上应该是可行的(CVPixelBufferpixel format types 下列出了 4 位格式),但我无法让它使用这种技术。
【讨论】: