1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 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 http://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
40//! [vpImageColorFromUIImage]
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}
88//! [vpImageColorFromUIImage]
89
90//! [vpImageGrayFromUIImage]
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
131    vpImage<unsigned char> gray;
132    vpImageConvert::convert(color, gray);
133
134    return gray;
135  }
136}
137//! [vpImageGrayFromUIImage]
138
139//! [UIImageFromVpImageColor]
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                                      NULL,                                       // 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}
173//! [UIImageFromVpImageColor]
174
175//! [UIImageFromVpImageGray]
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                                      NULL,                                       // 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}
209//! [UIImageFromVpImageGray]
210
211@end
212
213#endif
214
215