1 module rip.processing.grayscale;
2
3 private
4 {
5 import std.algorithm;
6 import std.range;
7
8 import rip.concepts.ranges;
9 import rip.concepts.templates;
10 import rip.concepts.color;
11 import rip.concepts.surface;
12 }
13
14 enum GrayPalette
15 {
16 STANDART,
17 LUMINANCE,
18 AVERAGE
19 }
20
21 auto toGrayScale(Range)(Range r, GrayPalette palette = GrayPalette.STANDART)
22 if(isPixelRange!Range)
23 {
24 RGBColor delegate(RGBColor) grayFunction;
25
26 final switch (palette) with (GrayPalette)
27 {
28 case STANDART:
29 grayFunction = delegate(RGBColor color) {
30 auto intensity = ((RGBColor color) => 0.2126 * color.red!float + 0.7152 * color.green!float + 0.0722 * color.blue!float);
31 return new RGBColor(intensity(color), intensity(color), intensity(color));
32 };
33 break;
34
35 case LUMINANCE:
36 grayFunction = delegate(RGBColor color) {
37 auto intensity = color.luminance!float;
38 return new RGBColor(intensity, intensity, intensity);
39 };
40 break;
41
42 case AVERAGE:
43 grayFunction = delegate(RGBColor color) {
44 auto intensity = (color.red!float + color.green!float + color.blue!float) / 3.0;
45 return new RGBColor(intensity, intensity, intensity);
46 };
47 break;
48 }
49 auto range = map!(a => grayFunction(a))(r).array;
50 return createPixels(range);
51 }
52
53 auto toGrayScale(Surface surface, GrayPalette palette = GrayPalette.STANDART)
54 {
55 auto image = surface
56 .createFences(1,1)
57 .map!(a => a.front)
58 .toGrayScale(palette)
59 .toSurface(surface.getWidth!int, surface.getHeight!int);
60 return image;
61 }