1 module rip.processing.colorization;
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 auto compareColors(RGBColor a, RGBColor b)
15 {
16 return a.distance!float(b);
17 }
18
19 // выборочная замена цвета (впоследстивие можно обобщить)
20 auto selectiveReplacing(Range)(Range r, RGBColor color, float detalizationLevel)
21 if(isPixelRange!Range)
22 {
23 // процедура замены цвета
24 auto replacingProcedure(RGBColor a, RGBColor b)
25 {
26 if (compareColors(a, b) <= detalizationLevel)
27 {
28 return a;
29 }
30 else
31 {
32 auto I = 0.2126 * a.red!float + 0.7152 * a.green!float + 0.0722 * a.blue!float;
33 return new RGBColor(I, I, I);
34 }
35 }
36
37 auto range = map!(a => replacingProcedure(a, color))(r).array;
38 return createPixels(range);
39 }
40
41
42 // замена цвета на другой
43 auto colorReplacing(Range)(Range r, RGBColor color, float detalizationLevel)
44 if(isPixelRange!Range)
45 {
46 // процедура замены цвета
47 auto replacingProcedure(RGBColor a, RGBColor b)
48 {
49 if (compareColors(a, b) <= detalizationLevel)
50 {
51 return b;
52 }
53 else
54 {
55 return a;
56 }
57 }
58
59 auto range = map!(a => replacingProcedure(a, color))(r).array;
60 return createPixels(range);
61 }
62
63 // простая замена одного цвета другим
64 auto simpleColorizing(Surface surface, RGBColor color, float detalizationLevel)
65 {
66 auto image = surface
67 .createFences(1,1)
68 .map!(a => a.front)
69 .colorReplacing(color, detalizationLevel)
70 .toSurface(surface.getWidth!int, surface.getHeight!int);
71 return image;
72 }
73
74 // выборочное обесцвечивание
75 auto selectiveColorizing(Surface surface, RGBColor color, float detalizationLevel)
76 {
77 auto image = surface
78 .createFences(1,1)
79 .map!(a => a.front)
80 .selectiveReplacing(color, detalizationLevel)
81 .toSurface(surface.getWidth!int, surface.getHeight!int);
82 return image;
83 }