c++ 如何在RGB332中创建抖动垂直渐变?

jbose2ul  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(109)

我正在尝试为ESPHome显示器编写一个函数,该函数将用颜色梯度填充给定的矩形。我正在使用RGB 332颜色的显示器,因为这一点,它创造了波段的颜色,而不是一个平滑的过渡。下面是我的代码:

void vGradient2(display::DisplayBuffer &it, int x1, int y1, int x2, int y2, Color &c1, Color &c2)
{
  for(int y = y1; y <= y2; y++){
    auto amnt = (float(y - y1) / float(y2 - y1)) * 255;
    it.line(x1, y, x2, y, c1.gradient(c2, amnt));
  }
}

我想知道我是否可以使用抖动-最好是拜耳抖动算法来改善这段代码。
是的,我试着问ChatGPT,它在几次迭代后生成的代码仍然没有给我想要的结果。我认为这是因为它总是计算颜色为255或0。

void vgrad3(display::DisplayBuffer &it, int x1, int y1, int x2, int y2, Color &color1, Color &color2) {
    // Compute the dimensions of the rectangle
    int width = x2 - x1 + 1;
    int height = y2 - y1 + 1;

    // Allocate memory for the Bayer matrix
    static uint8_t bayer[8][8] = {
        {0, 48, 12, 60, 3, 51, 15, 63},
        {32, 16, 44, 28, 35, 19, 47, 31},
        {8, 56, 4, 52, 11, 59, 7, 55},
        {40, 24, 36, 20, 43, 27, 39, 23},
        {2, 50, 14, 62, 1, 49, 13, 61},
        {34, 18, 46, 30, 33, 17, 45, 29},
        {10, 58, 6, 54, 9, 57, 5, 53},
        {42, 26, 38, 22, 41, 25, 37, 21}
    };

    // Iterate over each pixel in the rectangle
    for (int y = y1; y <= y2; y++) {
        for (int x = x1; x <= x2; x++) {
            // Compute the color of the pixel based on the vertical gradient
            float t = (float)(y - y1) / height;
            uint8_t r = color1.red * (1 - t) + color2.red * t;
            uint8_t g = color1.green * (1 - t) + color2.green * t;
            uint8_t b = color1.blue * (1 - t) + color2.blue * t;

            // Apply dithering using the Bayer matrix
            int bx = x % 8;
            int by = y % 8;
            uint8_t threshold = bayer[bx][by];
            uint8_t gray = (uint32_t)r * 77 + (uint32_t)g * 151 + (uint32_t)b * 28;
            uint8_t color = (gray > threshold * 255) ? 255 : 0; // I do not think this is right

            // Set the color of the pixel
            uint8_t red = (color & 0xE0) >> 5;
            uint8_t green = (color & 0x1C) >> 2;
            uint8_t blue = color & 0x03;
            uint8_t value = (red << 5) | (green << 2) | blue;
            it.draw_pixel_at(x, y, ColorUtil::rgb332_to_color(value));
        }
    }
}
guicsvcw

guicsvcw1#

RGB332是一种8位颜色,详情请参阅https://en.wikipedia.org/wiki/List_of_monochrome_and_RGB_color_formats。有256种不同的颜色。你期待什么样的平稳过渡?
另外,ChatGPT关于将32位值分配给8位变量有什么说明?:)

uint8_t gray = (uint32_t)r * 77 + (uint32_t)g * 151 + (uint32_t)b * 28;

正如你所建议的,这一行:

uint8_t color = (gray > threshold * 255) ? 255 : 0;// I do not think this is right

生成255(白色)或0(黑色)。不是我所说的“梯度”。
那个碎片

// Set the color of the pixel
        uint8_t red = (color & 0xE0) >> 5;
        uint8_t green = (color & 0x1C) >> 2;
        uint8_t blue = color & 0x03;

似乎分解和重新组合8位颜色,并且不更改原始值。

uint8_t value = (red << 5) | (green << 2) | blue;

最后,看起来ESPHome提供了一个gradient()函数:https://esphome.io/api/structesphome_1_1_color.html#abd2c92c49560dab88f43cfdeacf49138

相关问题