Visual Servoing Platform  version 3.6.1 under development (2024-04-23)
ImageConversion.mm
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31 *****************************************************************************/
32 
33 #ifndef DOXYGEN_SHOULD_SKIP_THIS
34 
35 #import "ImageConversion.h"
36 
37 @implementation ImageConversion
38 
39 
41 // Converts an UIImage that could be in gray or color into a ViSP color image
42 + (vpImage<vpRGBa>)vpImageColorFromUIImage:(UIImage *)image
43 {
44  CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
45 
46  if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome) {
47  NSLog(@"Input UIImage is grayscale");
48  vpImage<unsigned char> gray(image.size.height, image.size.width); // 8 bits per component, 1 channel
49 
50  CGContextRef contextRef = CGBitmapContextCreate(gray.bitmap, // pointer to data
51  image.size.width, // width of bitmap
52  image.size.height, // height of bitmap
53  8, // bits per component
54  image.size.width, // bytes per row
55  colorSpace, // colorspace
56  kCGImageAlphaNone |
57  kCGBitmapByteOrderDefault); // bitmap info flags
58 
59  CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
60  CGContextRelease(contextRef);
61 
62  vpImage<vpRGBa> color;
63  vpImageConvert::convert(gray, color);
64 
65  return color;
66  }
67  else {
68  NSLog(@"Input UIImage is color");
69  vpImage<vpRGBa> color(image.size.height, image.size.width); // 8 bits per component, 4 channels
70 
71  colorSpace = CGColorSpaceCreateDeviceRGB();
72 
73  CGContextRef contextRef = CGBitmapContextCreate(color.bitmap, // pointer to data
74  image.size.width, // width of bitmap
75  image.size.height, // height of bitmap
76  8, // bits per component
77  4 * image.size.width, // bytes per row
78  colorSpace, // colorspace
79  kCGImageAlphaNoneSkipLast |
80  kCGBitmapByteOrderDefault); // bitmap info flags
81 
82  CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
83  CGContextRelease(contextRef);
84 
85  return color;
86  }
87 }
89 
91 // Converts an UIImage that could be in gray or color into a ViSP gray image
92 + (vpImage<unsigned char>)vpImageGrayFromUIImage:(UIImage *)image
93 {
94  CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
95 
96  if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome) {
97  NSLog(@"Input UIImage is grayscale");
98  vpImage<unsigned char> gray(image.size.height, image.size.width); // 8 bits per component, 1 channel
99 
100  CGContextRef contextRef = CGBitmapContextCreate(gray.bitmap, // pointer to data
101  image.size.width, // width of bitmap
102  image.size.height, // height of bitmap
103  8, // bits per component
104  image.size.width, // bytes per row
105  colorSpace, // colorspace
106  kCGImageAlphaNone |
107  kCGBitmapByteOrderDefault); // bitmap info flags
108 
109  CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
110  CGContextRelease(contextRef);
111 
112  return gray;
113  } else {
114  NSLog(@"Input UIImage is color");
115  vpImage<vpRGBa> color(image.size.height, image.size.width); // 8 bits per component, 4 channels (color channels + alpha)
116 
117  colorSpace = CGColorSpaceCreateDeviceRGB();
118 
119  CGContextRef contextRef = CGBitmapContextCreate(color.bitmap, // pointer to data
120  image.size.width, // width of bitmap
121  image.size.height, // height of bitmap
122  8, // bits per component
123  4 * image.size.width, // bytes per row
124  colorSpace, // colorspace
125  kCGImageAlphaNoneSkipLast |
126  kCGBitmapByteOrderDefault); // bitmap info flags
127 
128  CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
129  CGContextRelease(contextRef);
130 
132  vpImageConvert::convert(color, gray);
133 
134  return gray;
135  }
136 }
138 
140 // Converts a color ViSP image into a color UIImage
141 + (UIImage *)UIImageFromVpImageColor:(const vpImage<vpRGBa> &)I
142 {
143  NSData *data = [NSData dataWithBytes:I.bitmap length:I.getSize()*4];
144  CGColorSpaceRef colorSpace;
145 
146  colorSpace = CGColorSpaceCreateDeviceRGB();
147 
148  CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
149 
150  // Creating CGImage from vpImage
151  CGImageRef imageRef = CGImageCreate(I.getWidth(), // width
152  I.getHeight(), // height
153  8, // bits per component
154  8 * 4, // bits per pixel
155  4 * I.getWidth(), // bytesPerRow
156  colorSpace, // colorspace
157  kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
158  provider, // CGDataProviderRef
159  nullptr, // decode
160  false, // should interpolate
161  kCGRenderingIntentDefault // intent
162  );
163 
164 
165  // Getting UIImage from CGImage
166  UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
167  CGImageRelease(imageRef);
168  CGDataProviderRelease(provider);
169  CGColorSpaceRelease(colorSpace);
170 
171  return finalImage;
172 }
174 
176 // Converts a gray level ViSP image into a gray level UIImage
177 + (UIImage *)UIImageFromVpImageGray:(const vpImage<unsigned char> &)I
178 {
179  NSData *data = [NSData dataWithBytes:I.bitmap length:I.getSize()];
180  CGColorSpaceRef colorSpace;
181 
182  colorSpace = CGColorSpaceCreateDeviceGray();
183 
184  CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
185 
186  // Creating CGImage from vpImage
187  CGImageRef imageRef = CGImageCreate(I.getWidth(), // width
188  I.getHeight(), // height
189  8, // bits per component
190  8, // bits per pixel
191  I.getWidth(), // bytesPerRow
192  colorSpace, // colorspace
193  kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
194  provider, // CGDataProviderRef
195  nullptr, // decode
196  false, // should interpolate
197  kCGRenderingIntentDefault // intent
198  );
199 
200 
201  // Getting UIImage from CGImage
202  UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
203  CGImageRelease(imageRef);
204  CGDataProviderRelease(provider);
205  CGColorSpaceRelease(colorSpace);
206 
207  return finalImage;
208 }
210 
211 @end
212 
213 #endif
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Definition of the vpImage class member functions.
Definition: vpImage.h:69
unsigned int getWidth() const
Definition: vpImage.h:245
unsigned int getHeight() const
Definition: vpImage.h:184
Definition: vpRGBa.h:61