Сортировка палитры RGB565
- Войдите на сайт для отправки комментариев
Ср, 08/08/2018 - 09:26
Может кто подсказать пример, как можно отсортировать набор цветов RGB565, находящиеся в случайном порядке что бы он соответсвовал спектру? Я находил и пробовал применить способы преобразования в HSL (HSV) и сортировку по hue и более менее что-то приближенное получалось, но все равно с третью цветов разбросанных как попало. Проблема в том, что все примеры рассчитаны на преобразование RGB888, и мне достаточно сложно на текущий момент понять, как можно примеры адаптировать под RGB565.
typedef struct RgbColor{
unsigned char r;
unsigned char g;
unsigned char b;
} RgbColor;
typedef struct HsvColor{
unsigned char h;
unsigned char s;
unsigned char v;
} HsvColor;
RgbColor HsvToRgb(HsvColor hsv){
RgbColor rgb;
unsigned char region, p, q, t;
unsigned int h, s, v, remainder;
if(hsv.s == 0){
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
return rgb;
}
// converting to 16 bit to prevent overflow
h = hsv.h;
s = hsv.s;
v = hsv.v;
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch(region){
case 0:
rgb.r = v;
rgb.g = t;
rgb.b = p;
break;
case 1:
rgb.r = q;
rgb.g = v;
rgb.b = p;
break;
case 2:
rgb.r = p;
rgb.g = v;
rgb.b = t;
break;
case 3:
rgb.r = p;
rgb.g = q;
rgb.b = v;
break;
case 4:
rgb.r = t;
rgb.g = p;
rgb.b = v;
break;
default:
rgb.r = v;
rgb.g = p;
rgb.b = q;
break;
}
return rgb;
}
HsvColor RgbToHsv(RgbColor rgb){
HsvColor hsv;
unsigned char rgbMin, rgbMax;
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
hsv.v = rgbMax;
if(hsv.v == 0){
hsv.h = 0;
hsv.s = 0;
return hsv;
}
hsv.s = 255 * ((long)(rgbMax - rgbMin)) / hsv.v;
if(hsv.s == 0){
hsv.h = 0;
return hsv;
}
if(rgbMax == rgb.r)
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
else if (rgbMax == rgb.g)
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
else
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
return hsv;
}
void sort(uint16_t a[], int size, uint16_t a2[]){
for(int i=0; i<(size-1); i++){
for(int o=0; o<(size-(i+1)); o++){
if(a[o] > a[o+1]){
int t = a[o];
a[o] = a[o+1];
a[o+1] = t;
int t2 = a2[o];
a2[o] = a2[o+1];
a2[o+1] = t2;
}
}
}
}
void colorsSort(){
//randomSeed(analogRead(0));
int len = 112; //16, 112
uint16_t arr[len] = {0};
uint16_t arr2[len] = {0};
byte bb[] = {5,6,5};
byte x = 0;
byte y = 0;
RgbColor rgb;
for(byte a=0; a<2; a++){
if(a) sort(arr2,len,arr);
for(int b=0; b<len; b++){
if(!a){
arr[b] = random(0,65536);
for(byte c=0, e=0; c<3; c++){
byte z = 0;
for(byte d=0; d<bb[c]; d++, e++){
bitWrite(z,d,bitRead(arr[b],e));
}
switch(c){
case 0 : rgb.r = z; break; //z << 3; break; //(z << 3) | (z >> 2); break; //z; break;
case 1 : rgb.g = z; break; //z << 2; break; //(z << 2) | (z >> 4); break; //z; break;
case 2 : rgb.b = z; break; //z << 3; break; //(z << 3) | (z >> 2); break; //z; break;
}
}
HsvColor hsv = RgbToHsv(rgb);
arr2[b] = hsv.h;
}
tft.fillRect(x,y,6,6,arr[b]);
x += 8;
if(x >= 122){
x = 0;
y += 8;
}
}
x = 0;
y += 8;
}
}
Это пример того что получается. До и после, типа.
https://pp.userapi.com/c846323/v846323252/bc1b7/K__ltXMXpLM.jpg
красиво.
что значит "чтобы соответствовал спектру"?
тут написано, что формат 15-16 битный а у вас 3 байта?
https://en.wikipedia.org/wiki/RGB565
текст программы не компилируется.
https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/HSV-RGB-compar... Что бы сортировались в таком или приближенном порядке. Что бы не были оттенки одного цвета разбросаны по всей палитре.
Да 16 битный, 5 - 6 - 5 бит на цвет, который я в силу своих познаний привел к байту каждый для передачи в конвертер.
Сейчас все соберу в один файл, ибо по кусочкам надрал что бы показать.
Что красиво?
https://www.dropbox.com/s/olgq9ity6sj0xk3/Test.7z?dl=0
Красивая фотография дисплея с нанкой на борде.
На нижней части изображения видна сортировка сверху вниз от синего до синего.
На этой палитре отсутствуют белый, серый, чёрный.
В ваших данных есть похожие цвета.
На нижней части изображения видна сортировка сверху вниз от синего до синего.
На этой палитре отсутствуют белый, серый, чёрный.
В ваших данных есть похожие цвета.
И как со всем этим справиться?)
Nefelisk, глядя на приведенное Вами фото, можно предположить, что сортировка осуществляется правильно. Только "спектр" представлен в виде круга, а "разорван" этот круг не совсем в нужном месте: между синим и фиолетовым вместо того, чтобы между фиолетовым и красным.
И еще: если хотите конкретного совета, четко сформулируйте проблему. Повторяю, по фото проблемы не видно.
Подниму старую тему,
балуюсь со спрайтами на STM32, дисплей 320*240 ili9341, отображение в формате RGB565, конвертацию во время вывода из обычного RGB888 легко можно сделать и быстродействия хватит, но хранить во flash в 24 битном формате картинки - расточительство.
Никто не встречал online сайт преобразования файлов или программу конвертации из RGB888/BMP в RGB565?
Никто не встречал online сайт преобразования файлов или программу конвертации из RGB888/BMP в RGB565?
вот http://www.rinkydinkelectronics.com/t_imageconverter565.php
Никто не встречал online сайт преобразования файлов или программу конвертации из RGB888/BMP в RGB565?
вот http://www.rinkydinkelectronics.com/t_imageconverter565.php
Спасибо, отлично работает, цвета правда съезжают, но надо над исходником поработать, это мелочи.
Мля.... Ребята, ну это же элементарная хрень :(
// пиксель RGB 16 бит struct _color16{ uint16_t c=0; void setRed(uint8_t r) {c= (c & 0x7FF) | (((uint16_t)r<<8) & 0xF800);} void setGreen(uint8_t g){c= (c & 0xF81F) | (((uint16_t)g<<3) & 0x7E0);} void setBlue(uint8_t b) {c= (c & 0xFFE0) | ( b>>3) ;} uint8_t getRed() { return ((c>>8) & 0xF8) | ((uint8_t)(c>>13));} uint8_t getGreen(){ return ((c>>3) & 0xFC) | ((uint8_t)(c>>8) & 0x7);} uint8_t getBlue() { return (c<<3) | ((uint8_t)(c>>2) & 0x7);} void set(uint8_t R, uint8_t G, uint8_t B){setRed(R); setGreen(G); setBlue(B);} void get(uint8_t* R, uint8_t* G, uint8_t* B){*R=getRed(); *G=getGreen(); *B=getBlue();} };Есть еще немного более продвинутый алгоритм, который копирует старшие биты цвета в обнуленные компрессией младшие, тогда диапазон расширяется вверх до максимальных 255. Но особого смысла в этом не вижу. Можно еще использовать табличное преобразование которое растянет диапазон 8...248 в 1...255, а оно ннада ?
Прочитал в пол глаза, ответил не в тему... Ну пусть остается.
// пиксель RGB 16 бит
struct _color16{ uint16_t c=0; void setRed(uint8_t r) {c= (c & 0x7FF) | (((uint16_t)r<<8) & 0xF800);} void setGreen(uint8_t g){c= (c & 0xF81F) | (((uint16_t)g<<3) & 0x7E0);} void setBlue(uint8_t b) {c= (c & 0xFFE0) | ( b>>3) ;} uint8_t getRed() { return ((c>>8) & 0xF8) | ((uint8_t)(c>>13));} uint8_t getGreen(){ return ((c>>3) & 0xFC) | ((uint8_t)(c>>8) & 0x7);} uint8_t getBlue() { return (c<<3) | ((uint8_t)(c>>2) & 0x7);} void set(uint8_t R, uint8_t G, uint8_t B){setRed(R); setGreen(G); setBlue(B);} void get(uint8_t* R, uint8_t* G, uint8_t* B){*R=getRed(); *G=getGreen(); *B=getBlue();} };Есть еще немного более продвинутый алгоритм, который копирует старшие биты цвета в обнуленные компрессией младшие, тогда диапазон расширяется вверх до максимальных 255. Но особого смысла в этом не вижу. Можно еще использовать табличное преобразование которое растянет диапазон 8...248 в 1...255, а оно ннада ?
На крошечном экране точность цветов нафиг не надо.
А на светодиодной ленте яркость сильно зависит от значений.
Никто не встречал online сайт преобразования файлов или программу конвертации из RGB888/BMP в RGB565?
вот http://www.rinkydinkelectronics.com/t_imageconverter565.php
Спасибо, отлично работает, цвета правда съезжают, но надо над исходником поработать, это мелочи.
Дополнение:
цвета в моем случае съезжали из за другой последовательности битов в 16 битном слове, что бы не изобретать велосипед, вышел из положения следующим способом:
1. преобразую по выше указанной ссылке jpg файл в raw
2. перевожу набор байтов в СИ массив ссылкой:
Bin2C — преобразование бинарных файлов в массив C/C++ (krivyy.com)