1 @implementation UIImage (grayscale)
2
3 typedef enum {
4
5 ALPHA = 0,
6
7 BLUE = 1,
8
9 GREEN = 2,
10
11 RED = 3
12
13 } PIXELS;
14
15 - (UIImage *)convertToGrayscale {
16
17 CGSize size = [self size];
18
19 int width = size.width;
20
21 int height = size.height;
22
23
24 // the pixels will be painted to this array
25
26 uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
27
28
29 // clear the pixels so any transparency is preserved
30
31 memset(pixels, 0, width * height * sizeof(uint32_t));
32
33
34 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
35
36
37 // create a context with RGBA pixels
38
39 CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
40
41 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
42
43
44 // paint the bitmap to our context which will fill in the pixels array
45
46 CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);
47
48
49 for(int y = 0; y < height; y++) {
50
51 for(int x = 0; x < width; x++) {
52
53 uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
54
55
56 // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
57
58 uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
59
60
61 // set the pixels to gray
62
63 rgbaPixel[RED] = gray;
64
65 rgbaPixel[GREEN] = gray;
66
67 rgbaPixel[BLUE] = gray;
68
69 }
70
71 }
72
73
74 // create a new CGImageRef from our context with the modified pixels
75
76 CGImageRef image = CGBitmapContextCreateImage(context);
77
78
79 // we're done with the context, color space, and pixels
80
81 CGContextRelease(context);
82
83 CGColorSpaceRelease(colorSpace);
84
85 free(pixels);
86
87
88 // make a new UIImage to return
89
90 UIImage *resultUIImage = [UIImage imageWithCGImage:image];
91
92
93 // we're done with image now too
94
95 CGImageRelease(image);
96
97
98 return resultUIImage;
99
100 }
101
102 @end
2
3 typedef enum {
4
5 ALPHA = 0,
6
7 BLUE = 1,
8
9 GREEN = 2,
10
11 RED = 3
12
13 } PIXELS;
14
15 - (UIImage *)convertToGrayscale {
16
17 CGSize size = [self size];
18
19 int width = size.width;
20
21 int height = size.height;
22
23
24 // the pixels will be painted to this array
25
26 uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
27
28
29 // clear the pixels so any transparency is preserved
30
31 memset(pixels, 0, width * height * sizeof(uint32_t));
32
33
34 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
35
36
37 // create a context with RGBA pixels
38
39 CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
40
41 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
42
43
44 // paint the bitmap to our context which will fill in the pixels array
45
46 CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);
47
48
49 for(int y = 0; y < height; y++) {
50
51 for(int x = 0; x < width; x++) {
52
53 uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
54
55
56 // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
57
58 uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
59
60
61 // set the pixels to gray
62
63 rgbaPixel[RED] = gray;
64
65 rgbaPixel[GREEN] = gray;
66
67 rgbaPixel[BLUE] = gray;
68
69 }
70
71 }
72
73
74 // create a new CGImageRef from our context with the modified pixels
75
76 CGImageRef image = CGBitmapContextCreateImage(context);
77
78
79 // we're done with the context, color space, and pixels
80
81 CGContextRelease(context);
82
83 CGColorSpaceRelease(colorSpace);
84
85 free(pixels);
86
87
88 // make a new UIImage to return
89
90 UIImage *resultUIImage = [UIImage imageWithCGImage:image];
91
92
93 // we're done with image now too
94
95 CGImageRelease(image);
96
97
98 return resultUIImage;
99
100 }
101
102 @end