// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "apple_conversions.h" #include "precomp.hpp" CGImageRef MatToCGImage(const cv::Mat& image) { NSData *data = [NSData dataWithBytes:image.data length:image.step.p[0] * image.rows]; CGColorSpaceRef colorSpace; if (image.elemSize() == 1) { colorSpace = CGColorSpaceCreateDeviceGray(); } else { colorSpace = CGColorSpaceCreateDeviceRGB(); } CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); // Preserve alpha transparency, if exists bool alpha = image.channels() == 4; CGBitmapInfo bitmapInfo = (alpha ? kCGImageAlphaLast : kCGImageAlphaNone) | kCGBitmapByteOrderDefault; // Creating CGImage from cv::Mat CGImageRef imageRef = CGImageCreate(image.cols, image.rows, 8 * image.elemSize1(), 8 * image.elemSize(), image.step.p[0], colorSpace, bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault ); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpace); return imageRef; } void CGImageToMat(const CGImageRef image, cv::Mat& m, bool alphaExist) { CGColorSpaceRef colorSpace = CGImageGetColorSpace(image); CGFloat cols = CGImageGetWidth(image), rows = CGImageGetHeight(image); CGContextRef contextRef; CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast; if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome) { m.create(rows, cols, CV_8UC1); // 8 bits per component, 1 channel bitmapInfo = kCGImageAlphaNone; if (!alphaExist) bitmapInfo = kCGImageAlphaNone; else m = cv::Scalar(0); contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8, m.step[0], colorSpace, bitmapInfo); } else if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelIndexed) { // CGBitmapContextCreate() does not support indexed color spaces. colorSpace = CGColorSpaceCreateDeviceRGB(); m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels if (!alphaExist) bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault; else m = cv::Scalar(0); contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8, m.step[0], colorSpace, bitmapInfo); CGColorSpaceRelease(colorSpace); } else { m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels if (!alphaExist) bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault; else m = cv::Scalar(0); contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8, m.step[0], colorSpace, bitmapInfo); } CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image); CGContextRelease(contextRef); }