Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将24位PNG图像转换为字节数组_Ios_Objective C_Opengl Es_Png - Fatal编程技术网

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

我想做以下几点:

  • 从24位PNG图像读取RGB颜色值
  • 求RGB值的平均值并将其存储到字节数组中
  • 我已经提供了我希望能够执行这两个步骤的函数。 My函数返回一个字节数组,但是所有元素的值都为0。 所以我猜我读错了图像数据

    我在阅读图像时出错了什么?(也许我的格式不正确)

    以下是我的功能:

    + (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;
    }