Ios 将24位PNG图像转换为字节数组
我想做以下几点:Ios 将24位PNG图像转换为字节数组,ios,objective-c,opengl-es,png,Ios,Objective C,Opengl Es,Png,我想做以下几点: 从24位PNG图像读取RGB颜色值 求RGB值的平均值并将其存储到字节数组中 我已经提供了我希望能够执行这两个步骤的函数。 My函数返回一个字节数组,但是所有元素的值都为0。 所以我猜我读错了图像数据 我在阅读图像时出错了什么?(也许我的格式不正确) 以下是我的功能: + (GLubyte *) LoadPhotoAveragedIndexPNG:(UIImage *)image numPixelComponents: (int)numComponents { // Lo
+ (GLubyte *) LoadPhotoAveragedIndexPNG:(UIImage *)image numPixelComponents: (int)numComponents
{
// Load an image and return byte array.
CGImageRef textureImage = image.CGImage;
if (textureImage == nil)
{
NSLog(@"LoadPhotoIndexPNG: Failed to load texture image");
return nil;
}
NSInteger texWidth = CGImageGetWidth(textureImage);
NSInteger texHeight = CGImageGetHeight(textureImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
GLubyte *indexedData = (GLubyte *)malloc(texWidth * texHeight);
GLubyte *rawData = (GLubyte *)malloc(texWidth * texHeight * numComponents);
CGContextRef textureContext = CGBitmapContextCreate(
rawData,
texWidth,
texHeight,
8,
texWidth * numComponents,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(textureContext,
CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),
textureImage);
CGContextRelease(textureContext);
int rawDataLength = texWidth * texHeight * numComponents;
for (int i = 0, j = 0; i < rawDataLength; i += numComponents)
{
GLubyte b = rawData[i];
GLubyte g = rawData[i + 1];
GLubyte r = rawData[i + 2];
indexedData[j++] = (r + g + b) / 3;
}
return indexedData;
}
+(GLubyte*)LoadPhotoAveragedIndexPNG:(UIImage*)图像numPixelComponents:(int)numComponents
{
//加载图像并返回字节数组。
CGImageRef textureImage=image.CGImage;
if(textureImage==nil)
{
NSLog(@“LoadPhotoIndexPNG:无法加载纹理图像”);
返回零;
}
NSInteger texWidth=CGImageGetWidth(纹理图像);
NSInteger texHeight=CGImageGetHeight(纹理图像);
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
GLubyte*indexedata=(GLubyte*)malloc(texWidth*texHeight);
GLubyte*rawData=(GLubyte*)malloc(texWidth*texHeight*numComponents);
CGContextRef textureContext=CGBitmapContextCreate(
原始数据,
texWidth,
特克斯高度,
8.
texWidth*numComponents,
色彩空间,
KCGIMAGEAlphaPremultipledLast);
CGCOLORSPACTERELEASE(色彩空间);
CGContextDrawImage(textureContext,
CGRectMake(0.0,0.0,(浮动)texWidth,(浮动)texHeight),
纹理图像);
CGContextRelease(textureContext);
int rawDataLength=texWidth*texHeight*numComponents;
for(int i=0,j=0;i
以下是测试图像im加载(PNG格式的RGB颜色空间):
如果参数
b
、g
和r
在上一个循环中产生正常值,请通过一些日志检查。犯错误的地方是indexedata[j++]=(r+g+b)/3代码>这3个参数的大小为1字节,不能这样求和。使用较大的整数,键入并将结果键入回数组。(您很可能会出现溢出)除了您原来的问题之外,这里还有一个主要问题(甚至可能与此相关)
此表达式将在字节大小的整数操作上执行。如果r+g+b之和大于GLubyte所能容纳的类型,它将溢出。每当您通过中间变量处理数据时(好的样式!),请选择足够大的变量类型,以容纳可能遇到的最大值。另一种方法是像
indexedData[j++] = ((uint16_t)r + (uint16_t)g + (uint16_t)b) / 3;
但是读起来很麻烦。另外,如果要处理已知大小的整数,请使用stdint.h
中的类型。你知道,你期望每个通道有8位。也可以在for increment子句中使用逗号运算符
uint8_t *indexedData = (GLubyte *)malloc(texWidth * texHeight);
/* ... */
for (int i = 0, j = 0; i < rawDataLength; i += numComponents, j++)
{
uint16_t b = rawData[i];
uint16_t g = rawData[i + 1];
uint16_t r = rawData[i + 2];
indexedData[j] = (r + g + b) / 3;
}
uint8*indexedata=(GLubyte*)malloc(texWidth*texHeight);
/* ... */
对于(int i=0,j=0;i
希望此链接对Hmmm有所帮助。关于溢出的观点非常好。我会试试看这是否有效。嗨,我把它改成了im类型转换为int,然后是device by 3,然后类型转换回一个字节。但是现在我得到了所有平均像素的值85。不确定发生了什么。也许是巧合,但255/3=85。奇怪的是,我测试图像中的大多数像素都是黑色的!事实证明,在读取图像之前,我首先将其转换为ARGB。因此,我通过读取4个组件来修复它,丢弃了第一个字节,即alpha组件。
indexedData[j++] = ((uint16_t)r + (uint16_t)g + (uint16_t)b) / 3;
uint8_t *indexedData = (GLubyte *)malloc(texWidth * texHeight);
/* ... */
for (int i = 0, j = 0; i < rawDataLength; i += numComponents, j++)
{
uint16_t b = rawData[i];
uint16_t g = rawData[i + 1];
uint16_t r = rawData[i + 2];
indexedData[j] = (r + g + b) / 3;
}