
#include <qblib.c> int main(int argc, char* argv[]) { screen(13); ditherpal(); float t = 0; while (sdlevent(EVT_REDRAW)) { cls(); useindex(0); for (int i = 0; i < 192; i++) for (int j = 0; j < 320; j++) { vec2 src_r = {160 + sin(t)*100, 100 + cos(t)*100}; vec2 src_g = {160 - sin(t)*100, 100 + cos(t)*100}; vec2 src_b = {160 + sin(t)*100, 100 - cos(t)*100}; int r = 255 - sqrt(pow(j-src_r.x, 2) + pow(i-src_r.y, 2)); int g = 255 - sqrt(pow(j-src_g.x, 2) + pow(i-src_g.y, 2)); int b = 255 - sqrt(pow(j-src_b.x, 2) + pow(i-src_b.y, 2)); pset(j, i, rgb(r, g, b)); } t = t + 0.01; int middle = 160 + 160*sin(t); line(middle, 0, middle, 192, 0xffffff); // Сам алгоритм ditherect(0, 0, middle, 192, 1); } return 0; }Найти ближайший цвет
int dither_search_nearest(rgbf& incl) { float dist_min = 4 * pow(256, 2); int dist_col = 0; // dospal for (int i = 0; i < 256; i++) { // Сравниваемый цвет struct rgbf cl = palette[i]; // Дистанция между точками (r`-r)^2 + (g`-g)^2 + (b`-b)^2 float dist = pow(incl.r - cl.r, 2) + pow(incl.g - cl.g, 2) + pow(incl.b - cl.b, 2); if (dist < dist_min) { dist_min = dist; dist_col = i; } } return dist_col; }Процедура дизеринга (left, top)-(right, bottom), dith=0 (nearest) 1(dithered)
void ditherect(int left, int top, int right, int bottom, int dith) { rgbf ws[QB_MAX_WIDTH][QB_MAX_HEIGHT]; int idx[QB_MAX_WIDTH][QB_MAX_HEIGHT]; // Копировать целочисленные точки в не целочисленные for (int y = top; y < bottom; y++) for (int x = left; x < right; x++) { ws[x][y] = { (float) qb_pixels[x][y].r, (float) qb_pixels[x][y].g, (float) qb_pixels[x][y].b }; } // Выполнить дизеринг for (int y = top; y < bottom; y++) for (int x = left; x < right; x++) { // Старые цвета rgbf old = ws[x][y]; // Поиск ближайшего цвета из палитры int color_id = dither_search_nearest(old); // Полученный индекс цвета idx[x][y] = color_id; // Учесть ошибки квантования if (dith) { // Заменить на новый цвет (из палитры) rgbf ncl = palette[]; // Отметить цвет @todo может это вообще не надо ws[x][y] = ncl; // Вычисляем ошибку квантования rgbf quant; quant.r = (old.r - ncl.r); quant.g = (old.g - ncl.g); quant.b = (old.b - ncl.b); // x 7 // 3 5 1 // [+1, +0] 7/16 if (x + 1 < right) { ws[x + 1][y].r += (quant.r * 7.0/16.0); ws[x + 1][y].g += (quant.g * 7.0/16.0); ws[x + 1][y].b += (quant.b * 7.0/16.0); } // [-1, +1] 3/16 if (x - 1 >= 0 && y + 1 < bottom) { ws[x - 1][y + 1].r += (quant.r * 3.0/16.0); ws[x - 1][y + 1].g += (quant.g * 3.0/16.0); ws[x - 1][y + 1].b += (quant.b * 3.0/16.0); } // [+0, +1] 5/16 if (y + 1 < bottom) { ws[x][y + 1].r += (quant.r * 5.0/16.0); ws[x][y + 1].g += (quant.g * 5.0/16.0); ws[x][y + 1].b += (quant.b * 5.0/16.0); } // [+1, +1] 1/16 if (x + 1 < right && y + 1 < bottom) { ws[x + 1][y + 1].r += (quant.r * 1.0/16.0); ws[x + 1][y + 1].g += (quant.g * 1.0/16.0); ws[x + 1][y + 1].b += (quant.b * 1.0/16.0); } } } }
13 июн, 2020
© 2007-2023 Бабушки знают цену прав на автомобиль