Merge pull request #18547 from mtfrctl:objc-conversions-macosx
Mat conversions for macOS/AppKit * Extract CoreGraphics conversion logics from ios_conversions.mm to apple_conversions.h, apple_conversions. Add macosx_conversions.mm * Add macosx.h * Add Mat+Conversions.h and Mat+Conversions.mm * Delete duplicated declaration from apple_conversion.mm * Use short license header * Add compile guard * Delete unused imports * Move precomp.hpp import from header to implementation * Add macosx.h to skip headers * Fix compile guard condition * Use short license header * Remove commented out unused code
This commit is contained in:
parent
4c048a487e
commit
7de189114b
@ -32,6 +32,7 @@
|
||||
opencv2/flann/hdf5.h
|
||||
opencv2/imgcodecs/imgcodecs_c.h
|
||||
opencv2/imgcodecs/ios.h
|
||||
opencv2/imgcodecs/macosx.h
|
||||
opencv2/videoio/videoio_c.h
|
||||
opencv2/videoio/cap_ios.h
|
||||
opencv2/xobjdetect/private.hpp
|
||||
|
||||
@ -113,10 +113,18 @@ file(GLOB imgcodecs_ext_hdrs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/legacy/*.h"
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/apple_conversions.h)
|
||||
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/apple_conversions.mm)
|
||||
endif()
|
||||
if(IOS)
|
||||
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/ios_conversions.mm)
|
||||
list(APPEND IMGCODECS_LIBRARIES "-framework UIKit" "-framework AssetsLibrary")
|
||||
endif()
|
||||
if(APPLE AND (NOT IOS))
|
||||
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/macosx_conversions.mm)
|
||||
list(APPEND IMGCODECS_LIBRARIES "-framework AppKit")
|
||||
endif()
|
||||
if(APPLE_FRAMEWORK)
|
||||
list(APPEND IMGCODECS_LIBRARIES "-framework Accelerate" "-framework CoreGraphics" "-framework QuartzCore")
|
||||
endif()
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
@{
|
||||
@defgroup imgcodecs_c C API
|
||||
@defgroup imgcodecs_ios iOS glue
|
||||
@defgroup imgcodecs_macosx MacOS(OSX) glue
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
20
modules/imgcodecs/include/opencv2/imgcodecs/macosx.h
Normal file
20
modules/imgcodecs/include/opencv2/imgcodecs/macosx.h
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
|
||||
#if !defined(__APPLE__) || !defined(__MACH__)
|
||||
#error This header should be used in macOS ObjC/Swift projects.
|
||||
#endif
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
//! @addtogroup imgcodecs_macosx
|
||||
//! @{
|
||||
|
||||
CV_EXPORTS CGImageRef MatToCGImage(const cv::Mat& image);
|
||||
CV_EXPORTS void CGImageToMat(const CGImageRef image, cv::Mat& m, bool alphaExist = false);
|
||||
CV_EXPORTS NSImage* MatToNSImage(const cv::Mat& image);
|
||||
CV_EXPORTS void NSImageToMat(const NSImage* image, cv::Mat& m, bool alphaExist = false);
|
||||
|
||||
//! @}
|
||||
32
modules/imgcodecs/misc/objc/macosx/Mat+Converters.h
Normal file
32
modules/imgcodecs/misc/objc/macosx/Mat+Converters.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Mat+Converters.h
|
||||
//
|
||||
// Created by Masaya Tsuruta on 2020/10/08.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#import "opencv.hpp"
|
||||
#else
|
||||
#define CV_EXPORTS
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "Mat.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
CV_EXPORTS @interface Mat (Converters)
|
||||
|
||||
-(CGImageRef)toCGImage;
|
||||
-(instancetype)initWithCGImage:(CGImageRef)image;
|
||||
-(instancetype)initWithCGImage:(CGImageRef)image alphaExist:(BOOL)alphaExist;
|
||||
-(NSImage*)toNSImage;
|
||||
-(instancetype)initWithNSImage:(NSImage*)image;
|
||||
-(instancetype)initWithNSImage:(NSImage*)image alphaExist:(BOOL)alphaExist;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
44
modules/imgcodecs/misc/objc/macosx/Mat+Converters.mm
Normal file
44
modules/imgcodecs/misc/objc/macosx/Mat+Converters.mm
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Mat+Converters.mm
|
||||
//
|
||||
// Created by Masaya Tsuruta on 2020/10/08.
|
||||
//
|
||||
|
||||
#import "Mat+Converters.h"
|
||||
#import <opencv2/imgcodecs/macosx.h>
|
||||
|
||||
@implementation Mat (Converters)
|
||||
|
||||
-(CGImageRef)toCGImage {
|
||||
return MatToCGImage(self.nativeRef);
|
||||
}
|
||||
|
||||
-(instancetype)initWithCGImage:(CGImageRef)image {
|
||||
return [self initWithCGImage:image alphaExist:NO];
|
||||
}
|
||||
|
||||
-(instancetype)initWithCGImage:(CGImageRef)image alphaExist:(BOOL)alphaExist {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
CGImageToMat(image, self.nativeRef, (bool)alphaExist);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSImage*)toNSImage {
|
||||
return MatToNSImage(self.nativeRef);
|
||||
}
|
||||
|
||||
-(instancetype)initWithNSImage:(NSImage*)image {
|
||||
return [self initWithNSImage:image alphaExist:NO];
|
||||
}
|
||||
|
||||
-(instancetype)initWithNSImage:(NSImage*)image alphaExist:(BOOL)alphaExist {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
NSImageToMat(image, self.nativeRef, (bool)alphaExist);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
11
modules/imgcodecs/src/apple_conversions.h
Normal file
11
modules/imgcodecs/src/apple_conversions.h
Normal file
@ -0,0 +1,11 @@
|
||||
// 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.
|
||||
|
||||
#import <Accelerate/Accelerate.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <ImageIO/ImageIO.h>
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
CV_EXPORTS CGImageRef MatToCGImage(const cv::Mat& image);
|
||||
CV_EXPORTS void CGImageToMat(const CGImageRef image, cv::Mat& m, bool alphaExist);
|
||||
94
modules/imgcodecs/src/apple_conversions.mm
Normal file
94
modules/imgcodecs/src/apple_conversions.mm
Normal file
@ -0,0 +1,94 @@
|
||||
// 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);
|
||||
}
|
||||
@ -41,105 +41,23 @@
|
||||
//M*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Accelerate/Accelerate.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <ImageIO/ImageIO.h>
|
||||
#include "opencv2/core.hpp"
|
||||
#include "precomp.hpp"
|
||||
#include "apple_conversions.h"
|
||||
|
||||
CV_EXPORTS UIImage* MatToUIImage(const cv::Mat& image);
|
||||
CV_EXPORTS void UIImageToMat(const UIImage* image, cv::Mat& m, bool alphaExist);
|
||||
|
||||
UIImage* MatToUIImage(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
|
||||
);
|
||||
|
||||
CGImageRef imageRef = MatToCGImage(image);
|
||||
|
||||
// Getting UIImage from CGImage
|
||||
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
|
||||
UIImage *uiImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
CGDataProviderRelease(provider);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return finalImage;
|
||||
return uiImage;
|
||||
}
|
||||
|
||||
void UIImageToMat(const UIImage* image,
|
||||
cv::Mat& m, bool alphaExist) {
|
||||
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
|
||||
CGFloat cols = CGImageGetWidth(image.CGImage), rows = CGImageGetHeight(image.CGImage);
|
||||
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.CGImage);
|
||||
CGContextRelease(contextRef);
|
||||
void UIImageToMat(const UIImage* image, cv::Mat& m, bool alphaExist) {
|
||||
CGImageRef imageRef = image.CGImage;
|
||||
CGImageToMat(imageRef, m, alphaExist);
|
||||
}
|
||||
|
||||
25
modules/imgcodecs/src/macosx_conversions.mm
Normal file
25
modules/imgcodecs/src/macosx_conversions.mm
Normal file
@ -0,0 +1,25 @@
|
||||
// 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.
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#include "apple_conversions.h"
|
||||
|
||||
CV_EXPORTS NSImage* MatToNSImage(const cv::Mat& image);
|
||||
CV_EXPORTS void NSImageToMat(const NSImage* image, cv::Mat& m, bool alphaExist);
|
||||
|
||||
NSImage* MatToNSImage(const cv::Mat& image) {
|
||||
// Creating CGImage from cv::Mat
|
||||
CGImageRef imageRef = MatToCGImage(image);
|
||||
|
||||
// Getting NSImage from CGImage
|
||||
NSImage *nsImage = [[NSImage alloc] initWithCGImage:imageRef size:CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef))];
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
return nsImage;
|
||||
}
|
||||
|
||||
void NSImageToMat(const NSImage* image, cv::Mat& m, bool alphaExist) {
|
||||
CGImageRef imageRef = [image CGImageForProposedRect:NULL context:NULL hints:NULL];
|
||||
CGImageToMat(imageRef, m, alphaExist);
|
||||
}
|
||||
@ -1584,6 +1584,11 @@ if __name__ == "__main__":
|
||||
if os.path.exists(ios_files_dir):
|
||||
copied_files += copy_objc_files(ios_files_dir, objc_base_path, module, True)
|
||||
|
||||
if args.target == 'osx':
|
||||
osx_files_dir = os.path.join(misc_location, 'macosx')
|
||||
if os.path.exists(osx_files_dir):
|
||||
copied_files += copy_objc_files(osx_files_dir, objc_base_path, module, True)
|
||||
|
||||
objc_test_files_dir = os.path.join(misc_location, 'test')
|
||||
if os.path.exists(objc_test_files_dir):
|
||||
copy_objc_files(objc_test_files_dir, objc_test_base_path, 'test', False)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user