从 RGBA 像素字节数据重建 UIImage 时出现问题

2024-03-10

我需要从单个灰度图像(红色、橙色、黄色等)创建 12 个彩色图像

源图像实际上是PNG、RGBA:

我正在使用我找到的一个库(https://github.com/PaulSolt/UIImage-Conversion/ https://github.com/PaulSolt/UIImage-Conversion/)将 UIImage 分解为 RGBA 字节数组,然后逐像素处理该数组,并使用相同的库重新构建新的 UIImage。

这是我的代码:

- (UIImage*) cloneWithTint3: (CGColorRef) cgTint
{
    enum { R, G, B, A };

    // - - - 

    assert( CGColorGetNumberOfComponents( cgTint ) == 4 );

    const float* tint = CGColorGetComponents( cgTint );

    // - - - 

    int w = self.size.width;
    int h = self.size.height;

    int pixelCount = w * h;


    uint8_t* data = [UIImage convertUIImageToBitmapRGBA8: self];

    for( int i=0; i < pixelCount ; i++ )
    {
        int offset = i << 2; // same as 4 * i but faster

        float in_r = data[ offset + R ];
        float in_g = data[ offset + G ];
        float in_b = data[ offset + B ];
//        float in_a = data[ offset + A ];

        if( i == 0  )
            printf( "ALPHA  %d ", data[ offset + A ] ); // corner pixel has alpha 0

        float greyscale = 0.30 * in_r  +  0.59 * in_g +  0.11 * in_b;

        data[ offset + R ] = (uint8_t) ( greyscale * tint[ R ] );
        data[ offset + G ] = (uint8_t) ( greyscale * tint[ G ] );
        data[ offset + B ] = (uint8_t) ( greyscale * tint[ B ] );
    }

    UIImage* imageNew = [UIImage convertBitmapRGBA8ToUIImage: data
                                                   withWidth: w
                                                  withHeight: h ];

    free( data );

    // test corner pixel
    {
        uint8_t* test = [UIImage convertUIImageToBitmapRGBA8: self];
        for( int i=0; i < 1 ; i++ )
        {
            int offset = i << 2;

            // float in_r = test[ offset + R ];
            // float in_g = test[ offset + G ];
            // float in_b = test[ offset + B ];
            // float in_a = data[ offset + A ];

            printf( "ALPHA  %d ", test[ offset + A ] ); // corner pixel still has alpha 0
        }

        free( test );
    }

    return imageNew;
}

问题是我没有恢复 Alpha 通道——它在各处将其设置为不透明。

如果我只是将源图像传递回第一行,它就会正确渲染,因此问题不在于源图像。

如果我检查第一个像素的 alpha 分量,我发现在该过程中的所有点上它都是 0(即透明),正如它应该的那样。正如您所看到的,我什至进行了额外的测试 - 一旦获得最终的 UIImage,我再次将其分解为 RGBA 位图并检查相同的元素。仍然是0。

所以看来convertUIImageToBitmapRGBA8方法中一定存在一些错误。看起来生成的 UIImage 上必须有一些设置,这使得它认为它到处都是不透明的。

但是查看这个方法的源代码(https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m-- 整个库只是这个文件及其标头)我看不出问题可能出在哪里。

这是渲染输出:

正如您所看到的,C 在 G 之前渲染,在 F 之前渲染,因此它的两侧都被矩形剪掉了。


Alpha 透明度问题已在最新的 github 推送中得到修复。https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m

解决方法是使用以下代码与函数中 bitmapInfo 中的 kCGImageAlphaPremultipliedLast 进行逻辑或运算。除了 CGImageRef 之外,还使用了 bitmapInfo 来增加 CGContextRef。两个 bitmapInfo 参数的格式应相同。

+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer 
                                withWidth:(int) width
                               withHeight:(int) height;

代码摘录:

CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    CGImageRef iref = CGImageCreate(width, 
                                    height, 
                                    bitsPerComponent, 
                                    bitsPerPixel, 
                                    bytesPerRow, 
                                    colorSpaceRef, 
                                    bitmapInfo, 
                                    provider,   // data provider
                                    NULL,       // decode
                                    YES,            // should interpolate
                                    renderingIntent);

    uint32_t* pixels = (uint32_t*)malloc(bufferLength);

    if(pixels == NULL) {
        NSLog(@"Error: Memory not allocated for bitmap");
        CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorSpaceRef);
        CGImageRelease(iref);       
        return nil;
    }

    CGContextRef context = CGBitmapContextCreate(pixels, 
                                                 width, 
                                                 height, 
                                                 bitsPerComponent, 
                                                 bytesPerRow, 
                                                 colorSpaceRef,
                                                 bitmapInfo);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 RGBA 像素字节数据重建 UIImage 时出现问题 的相关文章

  • 使用 BufferedImages 获取图像每个像素的颜色

    我试图获取图像的每个像素的每种颜色 我的想法如下 int pixels BufferedImage image image ImageIO read this getClass getResources image png int pixe
  • 将图像添加到 uitableview 单元格

    我有一个tableview 如何将图像添加到该单元格的左侧 cell imageView image UIImage imageNamed image png 更新 就像 Steven Fisher 所说 这应该只适用于具有 UITable
  • 使用 jQuery / JavaScript 将 Alpha 通道添加到背景颜色

    我有一个 jQuery 函数 它添加了一个Alpha通道到一个背景颜色当事件发生时 这是我的jsFiddle http jsfiddle net liormb SxQt8 1 CSS div background color rgb 100
  • 如何将图像转换为 UIImage?

    如何转换 SwiftUIImage to a UIImage let image Image systemName circle fill let UIImage image as UIImage 没有直接的方法将 Image 转换为 UI
  • Android 中使用黑白 alpha 蒙版的高效位图蒙版

    我想用黑白 alpha 蒙版来掩盖位图 我的蒙版图像是黑白的 黑色区域意味着透明 白色区域意味着不透明 我需要的是 当我使用此蒙版图像来蒙版任何其他图像时 如果蒙版图像的相应区域为黑色 则生成的图像区域应为透明 否则 生成的图像区域应该是不
  • iOS JPEG 图像旋转 90 度

    我正在使用选择器视图从相册中选择图像 我使用上面的代码 void imagePickerController UIImagePickerController picker didFinishPickingMediaWithInfo NSDi
  • 像素到厘米?

    我只是想知道像素单位是否是不变的 以及我们是否可以从像素转换为厘米 如同这个问题 https stackoverflow com questions 139655 how to convert pixels to points px to
  • 如何以编程方式使用资产目录图像的切片信息?

    我的项目中曾经有一个图像 我会像这样加载它 UIImage image UIImage imageNamed image name resizableImageWithCapInsets UIEdgeInsetsMake 10 0f 10
  • 将自定义图像设置为 UIBarButtonItem 但它不显示任何图像

    我想将自定义图像设置为 UIBarButtonItem 但它只显示周围的矩形框并且不显示实际图像 func setupBrowserToolbar let browser UIToolbar frame CGRect x 0 y 20 wi
  • iPhone/Objective-C - 呈现视图和委托时的 UIDocumentInteractionController 类参考

    我在用UIDocumentInteractionController在我的应用程序中 以便在我的应用程序中呈现 Instagram 过滤器屏幕 如下所述 http instagram com developer iphone hooks h
  • 避免 UIImage 的 imageNamed - 内存管理

    我正在经历这个链接 http akosma com 2009 01 28 10 iphone memory management tips 我遇到了一个点避免 UIImage 的 imageNamed 出于什么原因我们应该避免这种情况 它会
  • Android 自定义视图不能以正确的方式处理透明度/alpha

    我正在绘制自定义视图 在此视图中 我使用两个不同的绘画和路径对象在画布上绘画 我基本上是在绘制两个重叠的形状 添加 Alpha 后 视图中重叠的部分比图像的其余部分更暗 这是不希望的 但我不知道如何解决它 这是我的代码片段 用于展示我如何在
  • 如何在pygame中制作圆形曲面

    我需要创建一个具有边界圆的曲面 在该表面上绘制的任何内容在该边界圆之外都不应该是可见的 我尝试过使用蒙版 次表面 srcalpha 等 但似乎没有任何效果 我的尝试 w ss get width h ss get height TRANSP
  • 在 Swift 中上传带有其他参数的多张图片

    现在 我通过下面给出的代码仅将一张图像上传到服务器端脚本上的服务器 现在我有一个数组UIImage 我想知道如何使用UIImageJPEGRepresentation myImageView image 0 1 将所有图像发布到UIImag
  • 如何检查图像的特定像素是否透明?

    有什么方法可以检查 PNG 图像的选定 x y 点是否透明 根据 Jeff 的回答 您的第一步是创建 PNG 的画布表示 下面创建一个与图像宽度和高度相同的离屏画布 并在其上绘制图像 var img document getElementB
  • 我怎样才能将图像逐像素绘制到jframe

    我是java的初学者 直到今天我尝试做我自己认为的事情 所以这一天就在这里 我已经将图像的所有像素排列为 RGB 我想单击一个按钮并制作逐像素创建的类似动画的图像 这就是我所做的 但不起作用 import java awt BorderLa
  • 在 Matlab 中高效获取像素坐标

    我想在 Matlab 中创建一个函数 给定一个图像 该函数将允许人们通过单击图像中的像素来选择该像素并返回该像素的坐标 理想情况下 人们能够连续单击图像中的多个像素 并且该函数会将所有相应的坐标存储在一个矩阵中 有没有办法在Matlab中做
  • iPhone iOS 保存从 UIImageJPEGRepresentation() 获得的数据第二次失败:ImageIO: CGImageRead_mapData 'open' failed

    我的 UIImage 操作遇到了一个奇怪的问题 我正在进行保管箱同步 并且必须将我的图像存储为本地文件 为此 我使用以下命令保存它们UIImagePNGRepresentation image or UIImageJPEGRepresent
  • 如何褪色

    我想将像素的颜色淡化为白色 但显然保持相同的颜色 如果我有一个像素 200 120 40 将每个值加上 10 以使 210 130 50 使其颜色相同 只是颜色更浅 还是会完全改变颜色 例如 我知道 100 100 100 即将 110 1
  • 如何在禁用状态下更改 UIButton 图像 alpha?

    我有一个带有图像的 UIButton 在其禁用状态下 该图像应具有 0 3 alpha UIButton button UIButton buttonWithType UIButtonTypeCustom UIImage arrowImag

随机推荐