§ Квантование изображения
1#include <qblib.c>
2
3int main(int argc, char* argv[]) {
4
5 screen(13);
6 ditherpal();
7
8 float t = 0;
9 while (sdlevent(EVT_REDRAW)) {
10
11 cls();
12 useindex(0);
13
14 for (int i = 0; i < 192; i++)
15 for (int j = 0; j < 320; j++) {
16
17 vec2 src_r = {160 + sin(t)*100, 100 + cos(t)*100};
18 vec2 src_g = {160 - sin(t)*100, 100 + cos(t)*100};
19 vec2 src_b = {160 + sin(t)*100, 100 - cos(t)*100};
20
21 int r = 255 - sqrt(pow(j-src_r.x, 2) + pow(i-src_r.y, 2));
22 int g = 255 - sqrt(pow(j-src_g.x, 2) + pow(i-src_g.y, 2));
23 int b = 255 - sqrt(pow(j-src_b.x, 2) + pow(i-src_b.y, 2));
24
25 pset(j, i, rgb(r, g, b));
26 }
27
28 t = t + 0.01;
29 int middle = 160 + 160*sin(t);
30 line(middle, 0, middle, 192, 0xffffff);
31
32
33 ditherect(0, 0, middle, 192, 1);
34 }
35
36 return 0;
37}
Найти ближайший цвет
1int dither_search_nearest(rgbf& incl) {
2
3 float dist_min = 4 * pow(256, 2);
4 int dist_col = 0;
5
6
7 for (int i = 0; i < 256; i++) {
8
9
10 struct rgbf cl = palette[i];
11
12
13 float dist = pow(incl.r - cl.r, 2) +
14 pow(incl.g - cl.g, 2) +
15 pow(incl.b - cl.b, 2);
16
17 if (dist < dist_min) {
18
19 dist_min = dist;
20 dist_col = i;
21 }
22 }
23
24 return dist_col;
25}
Процедура дизеринга (left, top)-(right, bottom), dith=0 (nearest) 1(dithered)
1void ditherect(int left, int top, int right, int bottom, int dith) {
2
3 rgbf ws[QB_MAX_WIDTH][QB_MAX_HEIGHT];
4 int idx[QB_MAX_WIDTH][QB_MAX_HEIGHT];
5
6
7 for (int y = top; y < bottom; y++)
8 for (int x = left; x < right; x++) {
9
10 ws[x][y] = {
11 (float) qb_pixels[x][y].r,
12 (float) qb_pixels[x][y].g,
13 (float) qb_pixels[x][y].b
14 };
15 }
16
17
18 for (int y = top; y < bottom; y++)
19 for (int x = left; x < right; x++) {
20
21
22 rgbf old = ws[x][y];
23
24
25 int color_id = dither_search_nearest(old);
26
27
28 idx[x][y] = color_id;
29
30
31 if (dith) {
32
33
34 rgbf ncl = palette[];
35
36
37 ws[x][y] = ncl;
38
39
40 rgbf quant;
41
42 quant.r = (old.r - ncl.r);
43 quant.g = (old.g - ncl.g);
44 quant.b = (old.b - ncl.b);
45
46
47
48
49
50 if (x + 1 < right) {
51
52 ws[x + 1][y].r += (quant.r * 7.0/16.0);
53 ws[x + 1][y].g += (quant.g * 7.0/16.0);
54 ws[x + 1][y].b += (quant.b * 7.0/16.0);
55 }
56
57
58 if (x - 1 >= 0 && y + 1 < bottom) {
59
60 ws[x - 1][y + 1].r += (quant.r * 3.0/16.0);
61 ws[x - 1][y + 1].g += (quant.g * 3.0/16.0);
62 ws[x - 1][y + 1].b += (quant.b * 3.0/16.0);
63 }
64
65
66 if (y + 1 < bottom) {
67
68 ws[x][y + 1].r += (quant.r * 5.0/16.0);
69 ws[x][y + 1].g += (quant.g * 5.0/16.0);
70 ws[x][y + 1].b += (quant.b * 5.0/16.0);
71 }
72
73
74 if (x + 1 < right && y + 1 < bottom) {
75
76 ws[x + 1][y + 1].r += (quant.r * 1.0/16.0);
77 ws[x + 1][y + 1].g += (quant.g * 1.0/16.0);
78 ws[x + 1][y + 1].b += (quant.b * 1.0/16.0);
79 }
80 }
81 }
82}