【问题标题】:Generating a PNG with transparency from Mat (OpenCV)从 Mat (OpenCV) 生成具有透明度的 PNG
【发布时间】:2015-06-13 23:44:12
【问题描述】:

我正在做一些图像处理,在透明背景上创建图像。我正在使用 OpenCV (C++) 和 iOS。首先,我设置了一个 4 通道 8 位矩阵,将所有像素设置为白色,alpha 为 0(这是正确的吗?)。然后将像素从result复制到foreground

 cv::Mat foreground(image.size(),CV_8UC4, cv::Scalar(255,255,255,0));
 image.copyTo(foreground, result);

接下来,我需要将此Mat 转换为UIImage,我用于此的代码:

+(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
    CGColorSpaceRef colorSpace;

    if (cvMat.elemSize() == 1) {
        colorSpace = CGColorSpaceCreateDeviceGray();
    } else {
        colorSpace = CGColorSpaceCreateDeviceRGB();
    }

    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

    // Creating CGImage from cv::Mat
    CGImageRef imageRef = CGImageCreate(cvMat.cols,                                 //width
                                        cvMat.rows,                                 //height
                                        8,                                          //bits per component
                                        8 * cvMat.elemSize(),                       //bits per pixel
                                        cvMat.step[0],                            //bytesPerRow
                                        colorSpace,                                 //colorspace
                                        kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
                                        provider,                                   //CGDataProviderRef
                                        NULL,                                       //decode
                                        false,                                      //should interpolate
                                        kCGRenderingIntentDefault                   //intent
                                        );

    // Getting UIImage from CGImage
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);

    return finalImage;
}

这可以很好地生成我的图像,但我注意到它不透明。所以我想改用CGImageCreate,我可以使用:

CGImageRef imageRef = CGImageCreateWithPNGDataProvider(provider, NULL, false, kCGRenderingIntentDefault);

但是我不确定 CGImageCreateWithPNGDataProvider 是否是正确的调用,我不确定提供程序的格式是否正确。

我还检查了我的imageView.opaque = NO;

有人知道将cv::Mat 转换为PNG 的最简单方法吗?谢谢

*编辑:我还尝试在原始CGImageCreate 函数上修改位图信息的一些标志:

kCGImageAlphaPremultipliedLast,  /* For example, premultiplied RGBA */
  kCGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */
  kCGImageAlphaLast,               /* For example, non-premultiplied RGBA */
  kCGImageAlphaFirst,              /* For example, non-premultiplied ARGB */
  kCGImageAlphaNoneSkipLast,       /* For example, RBGX. */
  kCGImageAlphaNoneSkipFirst,      /* For example, XRGB. */

但是,我收到 <Error>: CGImageCreate: invalid image bits/pixel: 24. 的错误,我不确定如何解释,因为我用 4 个通道初始化了 cv::Mat foreground

【问题讨论】:

    标签: c++ ios opencv image-processing png


    【解决方案1】:

    看起来问题出在 copyTo 方法上。来自文档:

    该方法将矩阵数据复制到另一个矩阵。在复制数据之前,该方法调用

    m.create(this->size(), this->type());

    看起来它覆盖了您的 foreground 设置。您需要找到另一种方法来复制位以获取 Alpha 通道。

    【讨论】:

    • 我设置了任一标志,并将每像素位数设置为 32。但是,我现在的错误是 : CGImageCreate: invalid image bits/pixel or bytes/row。我当前每行的字节数设置为 cvMat.step[0],它返回 1410。我不确定这个值是什么意思。此外,每像素的旧位是用 8 * cvMat.elemSize() 计算的,但 elemSize 是 3。覆盖该评估是否错误?谢谢
    • @user339946 请检查更新的答案。 cvMat.elemSize() 返回的错误值是由于前景覆盖
    • 是的!问题是源图像是 3 通道并且缺少 alpha 值。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 2016-07-27
    • 2012-08-11
    • 2021-10-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多