I am doing some image manipulation which creates an image on a transparent background. I'm working with OpenCV (C++) and iOS. To begin, I setup a 4 channel 8 bit matrix, set all pixels to white with alpha 0 (is this correct?). Then copy the pixels from result
into foreground
:
cv::Mat foreground(image.size(),CV_8UC4, cv::Scalar(255,255,255,0));
image.copyTo(foreground, result);
Next, I need to convert this Mat
into a UIImage
, the code I was using for this:
+(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;
}
This works fine for generating my image, but I noticed it wasn't transparent. So I figured instead using CGImageCreate
, I could use:
CGImageRef imageRef = CGImageCreateWithPNGDataProvider(provider, NULL, false, kCGRenderingIntentDefault);
However I'm not sure if CGImageCreateWithPNGDataProvider is the right call, I'm not sure if the provider is formatted correctly for this method.
I have also checked to make sure my imageView.opaque = NO;
.
Does anyone know the easiest way to convert a cv::Mat
to PNG
with transparency? Thanks
*EDIT: I also tried tinkering with some of the flags for bitmap info on the original CGImageCreate
function:
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. */
However, I get an error of <Error>: CGImageCreate: invalid image bits/pixel: 24.
which I'm not sure how to interpret, since I initialized the cv::Mat foreground
with 4 channels.