I am using the code you provided to turn a cv::Mat into a UIImage. The code follows:
- (void) setImage:(cv::Mat ) cvMat {
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorSpace;
double min=0, max=0;
cv::minMaxLoc(cvMat, &min, &max);
NSLog(@"Min %f Max %f", min, max);
if (cvMat.elemSize() == 1) {
NSLog(@"Received gray-level image");
NSLog(@"W H: %d %d", cvMat.cols, cvMat.rows);
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], // cvMat.cols, //cvMat.step[0], //bytesPerRow
colorSpace, //colorspace
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
provider, //CGDataProviderRef
NULL, //decode
false, //should interpolate
kCGRenderingIntentDefault //intent
);
...
This code does not work in my program. The CGImageRef imageRef = CGImageCreate(cvMat.cols, ...
fails.
After a little bit of debugging, I noticed that after the following instruction:
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef) data);
all the input cvMat
fields are set to NULL
. See screenshots before & after.
What am I doing wrong?
The instruction is not executed in the main thread. I will try and move it into the main thread and see what happens, but its side effects should be documented somewhere...
BEFORE:
AFTER: