1. <small id='na9QX'></small><noframes id='na9QX'>

    <i id='na9QX'><tr id='na9QX'><dt id='na9QX'><q id='na9QX'><span id='na9QX'><b id='na9QX'><form id='na9QX'><ins id='na9QX'></ins><ul id='na9QX'></ul><sub id='na9QX'></sub></form><legend id='na9QX'></legend><bdo id='na9QX'><pre id='na9QX'><center id='na9QX'></center></pre></bdo></b><th id='na9QX'></th></span></q></dt></tr></i><div id='na9QX'><tfoot id='na9QX'></tfoot><dl id='na9QX'><fieldset id='na9QX'></fieldset></dl></div>
  2. <tfoot id='na9QX'></tfoot>
        <bdo id='na9QX'></bdo><ul id='na9QX'></ul>

    1. <legend id='na9QX'><style id='na9QX'><dir id='na9QX'><q id='na9QX'></q></dir></style></legend>

    2. 使用抖动将 24 位位图转换为 16 位的好的、优化的 C/C++ 算法是什么?

      时间:2023-12-02
        <bdo id='1uT9X'></bdo><ul id='1uT9X'></ul>
        • <tfoot id='1uT9X'></tfoot>
            1. <legend id='1uT9X'><style id='1uT9X'><dir id='1uT9X'><q id='1uT9X'></q></dir></style></legend>

              <small id='1uT9X'></small><noframes id='1uT9X'>

              <i id='1uT9X'><tr id='1uT9X'><dt id='1uT9X'><q id='1uT9X'><span id='1uT9X'><b id='1uT9X'><form id='1uT9X'><ins id='1uT9X'></ins><ul id='1uT9X'></ul><sub id='1uT9X'></sub></form><legend id='1uT9X'></legend><bdo id='1uT9X'><pre id='1uT9X'><center id='1uT9X'></center></pre></bdo></b><th id='1uT9X'></th></span></q></dt></tr></i><div id='1uT9X'><tfoot id='1uT9X'></tfoot><dl id='1uT9X'><fieldset id='1uT9X'></fieldset></dl></div>

                  <tbody id='1uT9X'></tbody>
              1. 本文介绍了使用抖动将 24 位位图转换为 16 位的好的、优化的 C/C++ 算法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我一直在寻找一种优化(即快速)算法,使用抖动将 24 位 RGB 位图转换为 16 位 (RGB565) 位图.我正在寻找 C/C++ 中的一些东西,我可以在其中实际控制如何应用抖动.GDI+ 似乎提供了一些方法,但我不知道它们是否会抖动.而且,如果他们确实抖动,他们使用的是什么机制(Floyd-Steinberg?)

                I've been looking for an optimized (i.e., quick) algorithm that converts a 24-bit RGB bitmap to a 16-bit (RGB565) bitmap using dithering. I'm looking for something in C/C++ where I can actually control how the dithering is applied. GDI+ seems to provide some methods, but I can't tell if they dither or not. And, if they do dither, what mechanism are they using (Floyd-Steinberg?)

                有没有人有使用抖动进行位图颜色深度转换的好例子?

                Does anyone have a good example of bitmap color-depth conversion with dithering?

                推荐答案

                正如您提到的,Floyd-Steinberg 抖动方法很受欢迎,因为它简单快速.对于 24 位和 16 位颜色之间的细微差异,结果在视觉上几乎是最佳的.

                As you mentioned, the Floyd-Steinberg dithering method is popular because it's simple and fast. For the subtle differences between 24-bit and 16-bit color the results will be nearly optimal visually.

                有人建议我使用示例图片 Lena 但我决定反对;尽管它作为测试图像的历史悠久,但我认为它对于现代情感来说过于性别歧视.相反,我展示了一张我自己的照片.首先是原始的,然后转换为抖动的 RGB565(并转换回 24 位用于显示).

                It was suggested that I use the sample picture Lena but I decided against it; despite its long history as a test image I consider it too sexist for modern sensibilities. Instead I present a picture of my own. First up is the original, followed by the conversion to dithered RGB565 (and converted back to 24-bit for display).

                和代码,在 C++ 中:

                And the code, in C++:

                inline BYTE Clamp(int n)
                {
                    n = n>255 ? 255 : n;
                    return n<0 ? 0 : n;
                }
                
                struct RGBTriplet
                {
                    int r;
                    int g;
                    int b;
                    RGBTriplet(int _r = 0, int _g = 0, int _b = 0) : r(_r), g(_g), b(_b) {};
                };
                
                void RGB565Dithered(const BYTE * pIn, int width, int height, int strideIn, BYTE * pOut, int strideOut)
                {
                    std::vector<RGBTriplet> oldErrors(width + 2);
                    for (int y = 0;  y < height;  ++y)
                    {
                        std::vector<RGBTriplet> newErrors(width + 2);
                        RGBTriplet errorAhead;
                        for (int x = 0;  x < width;  ++x)
                        {
                            int b = (int)(unsigned int)pIn[3*x] + (errorAhead.b + oldErrors[x+1].b) / 16;
                            int g = (int)(unsigned int)pIn[3*x + 1] + (errorAhead.g + oldErrors[x+1].g) / 16;
                            int r = (int)(unsigned int)pIn[3*x + 2] + (errorAhead.r + oldErrors[x+1].r) / 16;
                            int bAfter = Clamp(b) >> 3;
                            int gAfter = Clamp(g) >> 2;
                            int rAfter = Clamp(r) >> 3;
                            int pixel16 = (rAfter << 11) | (gAfter << 5) | bAfter;
                            pOut[2*x] = (BYTE) pixel16;
                            pOut[2*x + 1] = (BYTE) (pixel16 >> 8);
                            int error = r - ((rAfter * 255) / 31);
                            errorAhead.r = error * 7;
                            newErrors[x].r += error * 3;
                            newErrors[x+1].r += error * 5;
                            newErrors[x+2].r = error * 1;
                            error = g - ((gAfter * 255) / 63);
                            errorAhead.g = error * 7;
                            newErrors[x].g += error * 3;
                            newErrors[x+1].g += error * 5;
                            newErrors[x+2].g = error * 1;
                            error = b - ((bAfter * 255) / 31);
                            errorAhead.b = error * 7;
                            newErrors[x].b += error * 3;
                            newErrors[x+1].b += error * 5;
                            newErrors[x+2].b = error * 1;
                        }
                        pIn += strideIn;
                        pOut += strideOut;
                        oldErrors.swap(newErrors);
                    }
                }
                

                我不保证这段代码是完美的,我已经不得不修复我在另一条评论中提到的那些细微错误之一.但是它确实产生了上述结果.它采用 Windows 使用的 BGR 顺序的 24 位像素,并以小端顺序生成 R5G6B5 16 位像素.

                I won't guarantee this code is perfect, I already had to fix one of those subtle errors that I alluded to in another comment. However it did generate the results above. It takes 24-bit pixels in BGR order as used by Windows, and produces R5G6B5 16-bit pixels in little endian order.

                这篇关于使用抖动将 24 位位图转换为 16 位的好的、优化的 C/C++ 算法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:如何比 SetPixel() 更快地从原始 RGB 值数组直接在屏幕上显示像素? 下一篇:绘制 8bpp 灰度位图(非托管 C++)

                相关文章

                1. <i id='HpfQS'><tr id='HpfQS'><dt id='HpfQS'><q id='HpfQS'><span id='HpfQS'><b id='HpfQS'><form id='HpfQS'><ins id='HpfQS'></ins><ul id='HpfQS'></ul><sub id='HpfQS'></sub></form><legend id='HpfQS'></legend><bdo id='HpfQS'><pre id='HpfQS'><center id='HpfQS'></center></pre></bdo></b><th id='HpfQS'></th></span></q></dt></tr></i><div id='HpfQS'><tfoot id='HpfQS'></tfoot><dl id='HpfQS'><fieldset id='HpfQS'></fieldset></dl></div>
                  <legend id='HpfQS'><style id='HpfQS'><dir id='HpfQS'><q id='HpfQS'></q></dir></style></legend>
                  <tfoot id='HpfQS'></tfoot>

                2. <small id='HpfQS'></small><noframes id='HpfQS'>

                  • <bdo id='HpfQS'></bdo><ul id='HpfQS'></ul>