Blame view

3rdparty/opencv-4.5.4/modules/imgcodecs/src/apple_conversions.mm 3.71 KB
f4334277   Hu Chunming   提交3rdparty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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);
  }