Сообщение
ARV » Ср янв 04, 2017 22:07:02
попробуйте вот это - я накорябал сам на основе тех ссылок, которые вам рекомендовал. думаю, разберетесь...
Код: Выделить всё
/** \file rgb.c
* \par \author ARV \par
* \n \date 25 дек. 2016 г.
* Copyright 2015 © ARV. All rights reserved.
* \par
* Для компиляции требуется:\n
* -# Atmel Toolchain 3.4.5 или более новая версия
*/
#include <avr/io.h>
#include <avr_helper.h>
/// если этот макрос есть, оттенок (HUE для HSV-модели цвета) будет в градусах
/// иначе в условных единицах от 0 до 255
//#define HUE_SMOOTH
#if defined(HUE_SMOOTH)
#define hue_t uint16_t
#define HUE_MAX 360
#else
#define hue_t uint8_t
#define HUE_MAX 256
#endif
#define HUE_QUADRANT ((HUE_MAX + 5)/ 6)
typedef struct{
uint8_t r;
uint8_t g;
uint8_t b;
} color_rgb_t;
typedef struct{
hue_t h;
uint8_t s;
uint8_t v;
} color_hsv_t;
void hsv_to_rgb(const color_hsv_t *hsv, color_rgb_t *rgb);
void rgb_to_hsv(const color_rgb_t *rgb, color_hsv_t *hsv);
void hsv_to_rgb(const color_hsv_t *hsv, color_rgb_t *rgb){
uint8_t region, fpart, p, q, t;
if(hsv->s == 0) {
/* color is grayscale */
rgb->r = rgb->g = rgb->b = hsv->v;
return;
}
/* make hue 0-5 */
region = hsv->h / HUE_QUADRANT;
/* find remainder part, make it from 0-255 */
fpart = (hsv->h - (region * HUE_QUADRANT)) * 6;
/* calculate temp vars, doing integer multiplication */
p = (hsv->v * (255 - hsv->s)) >> 8;
q = (hsv->v * (255 - ((hsv->s * fpart) >> 8))) >> 8;
t = (hsv->v * (255 - ((hsv->s * (255 - fpart)) >> 8))) >> 8;
/* assign temp vars based on color cone region */
switch(region) {
case 0:
rgb->r = hsv->v; rgb->g = t; rgb->b = p; break;
case 1:
rgb->r = q; rgb->g = hsv->v; rgb->b = p; break;
case 2:
rgb->r = p; rgb->g = hsv->v; rgb->b = t; break;
case 3:
rgb->r = p; rgb->g = q; rgb->b = hsv->v; break;
case 4:
rgb->r = t; rgb->g = p; rgb->b = hsv->v; break;
default:
rgb->r = hsv->v; rgb->g = p; rgb->b = q; break;
}
}
#define MIN(x,y) ((x) < (y))?(x):(y)
#define MAX(x,y) ((x) > (y))?(x):(y)
void rgb_to_hsv(const color_rgb_t *rgb, color_hsv_t *hsv){
uint8_t min, max, delta;
int16_t hsvh;
min = MIN(rgb->r, MIN(rgb->g, rgb->b));
max = MAX(rgb->r, MAX(rgb->g, rgb->b));
hsv->v = max; // v, 0..255
delta = max - min; // 0..255, < v
if(max != 0)
hsv->s = (int)(delta)*255 / max; // s, 0..255
else {
// r = g = b = 0 // s = 0, v is undefined
hsv->s = 0;
hsv->h = 0;
return;
}
if(rgb->r == max)
hsvh = (rgb->g - rgb->b)*HUE_QUADRANT/delta; // between yellow & magenta
else if(rgb->g == max)
hsvh = (HUE_QUADRANT*2) + (rgb->b - rgb->r)*HUE_QUADRANT/delta; // between cyan & yellow
else
hsvh = (HUE_QUADRANT*4) + (rgb->r - rgb->g)*HUE_QUADRANT/delta; // between magenta & cyan
if(hsvh < 0) hsvh += HUE_MAX;
hsv->h = hsvh;
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик ... заходите!