搜索
bottom↓
回复: 2

谁能给一个HSV转RGB(整数运算的)的函数?

[复制链接]

出0入0汤圆

发表于 2022-12-26 16:34:33 | 显示全部楼层 |阅读模式
类似:
typedef u32 COLORREF;
#define RGB(r,g,b)        ((COLORREF)(((u8)(b)|((u32)((u8)(r))<<8))|(((u32)(u8)(g))<<16)))


COLORREF HSV(u8 h, u8 s, u8 v)
{

  return xxx
}

出0入0汤圆

 楼主| 发表于 2022-12-26 17:41:14 | 显示全部楼层
git上找到一个

#include <Arduino.h>
#include <FastLED.h>
#include "Hsv2rgbw16.h"


HSV16 HSV8toHSV16(CHSV inVal) {
    HSV16 retVal;

    retVal.h = (uint16_t) (inVal.h) << 8;
    if (inVal.s == 0xFF)
        retVal.s = 0xFFFF;
    else
        retVal.s = (uint16_t) (inVal.s) << 8;
    if (inVal.v == 0xFF)
        retVal.v = 0xFFFF;
    else
        retVal.v = (uint16_t) (inVal.v) << 8;
    return retVal;
}

CHSV HSV16toHSV8(HSV16 inVal) {
    CHSV retVal;

    retVal.h = (uint8_t) (inVal.h >> 8);
    retVal.s = (uint8_t) (inVal.s >> 8);
    retVal.v = (uint8_t) (inVal.v >> 8);
    return retVal;
}


void HSV16toRGBW16(HSV16 cHSV16, RGBW16 *cRGBW16) {
  // Yellow has a higher inherent brightness than
  // any other color; 'pure' yellow is perceived to
  // be 93% as bright as white.  In order to make
  // yellow appear the correct relative brightness,
  // it has to be rendered brighter than all other
  // colors.
  // Level Y1 is a moderate boost, the default.
  // Level Y2 is a strong boost.
  const uint8_t Y1 = 1;
  const uint8_t Y2 = 0;
  
  // G2: Whether to divide all greens by two.
  // Depends GREATLY on your particular LEDs
  const uint8_t G2 = 0;
  
  // Gscale: what to scale green down by.
  // Depends GREATLY on your particular LEDs
  const uint16_t Gscale = 0;
  
  uint16_t hue = cHSV16.h;
  uint16_t sat = cHSV16.s;
  uint16_t val = cHSV16.v;

  uint16_t offset = hue & (0x1FFF); // 0..31
  //Serial.print("Offset = ");
  //Serial.print(offset);

  
  // offset8 = offset * 8
  uint16_t offset8 = (offset << 3);

  //Serial.print("  Offset8 = ");
  //Serial.print(offset8);


  uint16_t third = scale16( offset8, (65536 / 3)); // max = 85
   
  //Serial.print("  Third = ");
  //Serial.print(third);
  
  uint16_t r, g, b, w;
   
  w = 0;
  if( ! (hue & 0x8000) ) {
      // 0XX
      if( ! (hue & 0x4000) ) {
          // 00X
          //section 0-1
          if( ! (hue & 0x2000) ) {
              // 000
              //case 0: // R -> O
              r = (65535) - third;
              g = third;
              b = 0;
          } else {
              // 001
              //case 1: // O -> Y
              if( Y1 ) {
                  r = (171 << 8);
                  g = (85 << 8) + third ;
                  b = 0;
              }
              if( Y2 ) {
                  r = (170 << 8) + third;
                  uint16_t twothirds = (third << 1);
                  //old: uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170
                  g = (85 << 8) + twothirds;
                  b = 0;
              }
          }
      } else {
          //01X
          // section 2-3
          if( !  (hue & 0x2000) ) {
              // 010
              //case 2: // Y -> G
              if( Y1 ) {
                  uint16_t twothirds = (third << 1);
                  // old: uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170
                  r = (171 << 8) - twothirds;
                  g = (170 << 8) + third;
                  b = 0;
              }
              if( Y2 ) {
                  r = 65535 - offset8;
                  g = 65535;
                  b = 0;
              }
          } else {
              // 011
              // case 3: // G -> A
              r = 0;
              g = 65535 - third;
              b = third;
          }
      }
  } else {
      // section 4-7
      // 1XX
      if( ! (hue & 0x4000) ) {
          // 10X
          if( ! ( hue & 0x2000) ) {
              // 100
              //case 4: // A -> B
              r = 0;
              uint16_t twothirds = (third << 1);
              // old: uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); // max=170
              g = (171 << 8) - twothirds; //K170?
              b = (85 << 8)  + twothirds;
              
          } else {
              // 101
              //case 5: // B -> P
              r = third;
              g = 0;
              b = 65535 - third;
              
          }
      } else {
          if( !  (hue & 0x2000)  ) {
              // 110
              //case 6: // P -- K
              r = (85 << 8) + third;
              g = 0;
              b = (171 << 8) - third;
              
          } else {
              // 111
              //case 7: // K -> R
              r = (170 << 8) + third;
              g = 0;
              b = (85 << 8) - third;
              
          }
      }
  }
  // This is one of the good places to scale the green down,
  // although the client can scale green down as well.
  if( G2 ) g = g >> 1;
  // old: if( Gscale ) g = scale8_video_LEAVING_R1_DIRTY( g, Gscale);
  if ( Gscale ) g = scale16(g, Gscale); // Note this is not a "video" scale
  
  // Scale down colors if we're desaturated at all
  // and add the brightness_floor to r, g, and b.
  if( sat != 65535 ) {
    if( sat == 0) {
      r = 0; b = 0; g = 0; w = 65535;
    }
    else {
      w = 0;
      if( r ) r = scale16( r, sat);
      if( g ) g = scale16( g, sat);
      if( b ) b = scale16( b, sat);
      //Serial.print("  SScaled R = ");
      //Serial.print(r);

            
      uint16_t desat = 65535 - sat;
      //Serial.print("  Desat = ");
      //Serial.print(desat);

      desat = scale16( desat, desat);
      
      uint16_t brightness_floor = desat;
      //Serial.print("  Floor = ");
      //Serial.print(brightness_floor);

      r += brightness_floor;
      g += brightness_floor;
      b += brightness_floor;
      //Serial.print("  Floored R = ");
      //Serial.print(r);

    }
  }
   
  // Now scale everything down if we're at value < 255.
  if( val != 65535 ) {
    val = scale16( val, val);
    //Serial.print("  Scaled Val = ");
    //Serial.print(val);

    if( val == 0 ) {
      r=0; g=0; b=0; w = 0;
    }
    else {
      // nscale8x3_video( r, g, b, val);
      if( r ) r = scale16( r, val);
      if( g ) g = scale16( g, val);
      if( b ) b = scale16( b, val);
      if( w ) w = scale16( w, val);
      //Serial.print("  VScaled R = ");
      //Serial.println(r);

    }
  }
   
  (*cRGBW16).r = r;
  (*cRGBW16).g = g;
  (*cRGBW16).b = b;
  (*cRGBW16).w = w;
}

出0入90汤圆

发表于 2022-12-26 17:54:39 | 显示全部楼层
https://github.com/FastLED/FastLED/blob/master/src/hsv2rgb.cpp



回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-4 12:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表