Reputation: 1071
i'm using opencv with Xcode , i get this method to convert from IplImage to UIImage:
-(UIImage *)UIImageFromIplImage:(IplImage *)image {
NSLog(@"IplImage (%d, %d) %d bits by %d channels, %d bytes/row %s", image->width, image->height, image->depth, image->nChannels, image->widthStep, image->channelSeq);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData *data = [NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(image->width, image->height,
image->depth, image->depth * image->nChannels, image->widthStep,
colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault,
provider, NULL, false, kCGRenderingIntentDefault);
UIImage *ret = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ret;
}
the problem is, when i pass any image to this method(png,jpg,tiff) this error appears : CGImageCreate: invalid image bits/pixel: 8, please help me in resolving that error,thanks.
Upvotes: 2
Views: 10091
Reputation: 86
if your image is gray(not RGBA), use this:
colorSpace = CGColorSpaceCreateDeviceGray();
Upvotes: 3
Reputation: 9379
From what I've done in my apps, you actually need to provide an alpha value in your image data. What I do, is taking the data out of the opencv struct, add an alpha value, and create the CGImage. Here is the code I use with the C++ API (if you stick to C just replace the call to aMat.ptr<>(y) by a pointer to the first pixel of the y-th row):
// Colorspace
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char* data = new unsigned char[4*aMat.cols*aMat.rows];
for (int y = 0; y < aMat.rows; ++y)
{
cv::Vec3b *ptr = aMat.ptr<cv::Vec3b>(y);
unsigned char *pdata = data + 4*y*aMat.cols;
for (int x = 0; x < aMat.cols; ++x, ++ptr)
{
*pdata++ = (*ptr)[2];
*pdata++ = (*ptr)[1];
*pdata++ = (*ptr)[0];
*pdata++ = 0;
}
}
// Bitmap context
CGContextRef context = CGBitmapContextCreate(data, aMat.cols, aMat.rows, 8, 4*aMat.cols, colorSpace, kCGImageAlphaNoneSkipLast);
CGImageRef cgimage = CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
delete[] data;
The shuffling part is necessary because OpenCV handles BGR images, while Quartz expects RGB.
Upvotes: 2