OpenCV -> UIImage
cv::Mat mat /* = ... */;
UIImage* image = [UIImage fromCvMat:mat];UIImage -> OpenCV
UIImage* image /* = ... */;
cv::Mat mat = [UIImage toCvMat:image];Original conversion code from OpenCV iOS tutorial, video processing
OpenCV -> UIImage
cv::Mat mat /* = ... */;
UIImage* image = [UIImage fromCvMat:mat];UIImage -> OpenCV
UIImage* image /* = ... */;
cv::Mat mat = [UIImage toCvMat:image];Original conversion code from OpenCV iOS tutorial, video processing
| #import <UIKit/UIKit.h> | |
| #ifdef __cplusplus | |
| #pragma clang diagnostic push | |
| #pragma clang diagnostic ignored "-Wdocumentation" | |
| #import <opencv2/core/core.hpp> | |
| #pragma clang pop | |
| #endif | |
| @interface UIImage (UIImage_OpenCvConversion) | |
| #ifdef __cplusplus | |
| + (cv::Mat)toCvMat:(UIImage *)image; | |
| + (cv::Mat)toCvMatGray:(UIImage *)image; | |
| + (UIImage *)fromCvMat:(cv::Mat)cvMat; | |
| #endif | |
| @end |
| #import "UIImage+OpenCvConversion.h" | |
| #ifdef __cplusplus | |
| #pragma clang diagnostic push | |
| #pragma clang diagnostic ignored "-Wdocumentation" | |
| #import <opencv2/core/core.hpp> | |
| #import <opencv2/imgproc/imgproc.hpp> | |
| #pragma clang pop | |
| #endif | |
| @implementation UIImage (UIImage_OpenCvConversion) | |
| #ifdef __cplusplus | |
| + (cv::Mat)toCvMat:(UIImage *)image | |
| { | |
| CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); | |
| CGFloat cols = image.size.width; | |
| CGFloat rows = image.size.height; | |
| cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha) | |
| CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data | |
| cols, // Width of bitmap | |
| rows, // Height of bitmap | |
| 8, // Bits per component | |
| cvMat.step[0], // Bytes per row | |
| colorSpace, // Colorspace | |
| kCGImageAlphaNoneSkipLast | | |
| kCGBitmapByteOrderDefault); // Bitmap info flags | |
| CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); | |
| CGContextRelease(contextRef); | |
| return cvMat; | |
| } | |
| + (cv::Mat)toCvMatGray:(UIImage *)image | |
| { | |
| CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); | |
| CGFloat cols = image.size.width; | |
| CGFloat rows = image.size.height; | |
| cv::Mat cvMat(rows, cols, CV_8UC1); // 8 bits per component, 1 channels | |
| CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data | |
| cols, // Width of bitmap | |
| rows, // Height of bitmap | |
| 8, // Bits per component | |
| cvMat.step[0], // Bytes per row | |
| colorSpace, // Colorspace | |
| kCGImageAlphaNoneSkipLast | | |
| kCGBitmapByteOrderDefault); // Bitmap info flags | |
| CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); | |
| CGContextRelease(contextRef); | |
| return cvMat; | |
| } | |
| + (UIImage *)fromCvMat:(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; | |
| } | |
| #endif | |
| @end |