从 Mat (OpenCV) 生成具有透明度的 PNG
Generating a PNG with transparency from Mat (OpenCV)
我正在做一些图像处理,在透明背景上创建图像。我正在使用 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
。
看起来问题出在 copyTo 方法上。来自文档:
The method copies the matrix data to another matrix. Before copying the data, the method invokes
m.create(this->size(), this->type());
它似乎覆盖了您对 前景 的设置。您需要找到另一种方法来复制位以获得 alpha 通道。
我正在做一些图像处理,在透明背景上创建图像。我正在使用 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
。
看起来问题出在 copyTo 方法上。来自文档:
The method copies the matrix data to another matrix. Before copying the data, the method invokes
m.create(this->size(), this->type());
它似乎覆盖了您对 前景 的设置。您需要找到另一种方法来复制位以获得 alpha 通道。