首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用GDI渲染8位索引位图?

如何使用GDI渲染8位索引位图?
EN

Stack Overflow用户
提问于 2013-01-18 11:28:02
回答 2查看 2K关注 0票数 1

我正在尝试使用windows GDI将freetype的字形渲染到一个窗口中。由freetype生成的位图似乎是8位索引位图之类的,因为在它的官方教程example4.cpp中,它使用Qt来呈现如下字形:

代码语言:javascript
复制
error = FT_Render_Glyph(m_face->glyph,
                    FT_RENDER_MODE_NORMAL);

            QImage glyphImage(m_face->glyph->bitmap.buffer,
                m_face->glyph->bitmap.width,
                m_face->glyph->bitmap.rows,
                m_face->glyph->bitmap.pitch,
                QImage::Format_Indexed8);

            /*painter.translate(m_glyphRect.x(),
                m_glyphRect.y());*/

            QVector<QRgb> colorTable;
            for (int i = 0; i < 256; ++i)
                colorTable << qRgba(0, 0, 0, i);
            glyphImage.setColorTable(colorTable);

            painter.drawImage(QPoint(0, 0),
                glyphImage);

因此,我尝试使用gdi呈现它,如下所示:

代码语言:javascript
复制
BITMAPINFO* pBmi = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);
            BITMAPINFOHEADER &bmh = pBmi->bmiHeader;
            bmh.biSize = sizeof(BITMAPINFOHEADER);
            bmh.biBitCount = 8;
            bmh.biCompression = BI_RGB;
            bmh.biPlanes = 1;
            RGBQUAD* palette = &pBmi->bmiColors[0];
            for (int i = 0; i < 256; ++i) {
                RGBQUAD rgb = {0};
                palette[i] = rgb;
            }

            //assert(pBm->bitmap);
            bmh.biWidth = pBm->bitmap.width;
            bmh.biHeight =  - pBm->bitmap.rows;
            StretchDIBits(hdc, 200, 200, pBm->bitmap.width, pBm->bitmap.rows, 0, 0, pBm->bitmap.width, pBm->bitmap.rows, pBm->bitmap.buffer, 
                pBmi, DIB_PAL_COLORS, SRCCOPY);

然后我尝试使用GDI+来渲染,但也失败了。

代码语言:javascript
复制
error = FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_NORMAL);
            Bitmap bitmap(pBm->bitmap.width, pBm->bitmap.rows, pBm->bitmap.pitch, PixelFormat8bppIndexed, pBm->bitmap.buffer);
            //Bitmap bitmap(pBm->bitmap.width, pBm->bitmap.rows, 64, PixelFormat8bppIndexed, pBm->bitmap.buffer);
            ColorPalette* pal = (ColorPalette*)malloc(sizeof(ColorPalette) + 255 * sizeof(ARGB));
            pal->Flags = PaletteFlagsGrayScale;
            pal->Count = 256;
            for (int i = 0; i <= 255; i++) {
                pal->Entries[i] = Color::MakeARGB(i, 0, 0, 0);
            }
            bitmap.SetPalette(pal);
            Graphics graphics(hdc);
            graphics.DrawImage(&bitmap, 100, 100);

你能告诉我,如何使用GDI/GDI+在Windows中渲染每像素8位的索引位图吗?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-18 13:16:30

您给出的Qt示例创建了一个全黑的调色板,其透明度随强度而变化。在GDI中使用的调色板都是黑色的,句号。你需要改变颜色。

票数 1
EN

Stack Overflow用户

发布于 2013-01-18 13:36:37

正如这里所说的:

代码语言:javascript
复制
        hdc = BeginPaint(hWnd, &ps);

        assert(Draw());

        FT_GlyphSlot &pBm = m_face->glyph;

        //output by console
        {
            printf("\n");
            for (int j = 0; j < pBm->bitmap.rows; j++) {
                printf("\n");
                for (int i = 0; i < pBm->bitmap.width; i++) 
                    printf("%2x", pBm->bitmap.buffer[j * pBm->bitmap.width + i]);
            }
        }

        //output by gdi+
        {
            Bitmap *pBitmap = NULL;
            LPBYTE pBuffer = NULL;      
            int stride = (pBm->bitmap.pitch + 3) / 4 * 4;
            if (stride != pBm->bitmap.pitch)
            {
                pBuffer = new BYTE[stride * pBm->bitmap.rows];
                memset(pBuffer, 0, stride * pBm->bitmap.rows);
                for (int i = 0; i < pBm->bitmap.rows; i++)
                    for (int j = 0; j < pBm->bitmap.width; j++)
                        pBuffer[i * stride + j] = pBm->bitmap.buffer[i * pBm->bitmap.width + j];
            } else
            {
                pBuffer = pBm->bitmap.buffer;
            }
            pBitmap = new Bitmap(pBm->bitmap.width, pBm->bitmap.rows, stride, PixelFormat8bppIndexed, pBuffer);
            ColorPalette *pPalette = (ColorPalette*)malloc(sizeof(ColorPalette) + 255 * sizeof(ARGB));
            pPalette->Count = 256;
            pPalette->Flags = PaletteFlagsGrayScale;
            ARGB* pColor = &pPalette->Entries[0];
            for (int i = 0; i < 256; i++)
                pColor[i] = Color::MakeARGB(i, 0x00, 0x00, 0x00);
            assert(pBitmap->GetLastStatus() == Ok);
            pBitmap->SetPalette(pPalette);
            assert(pBitmap->GetLastStatus() == Ok);
            Graphics graphics(hdc);
            graphics.DrawImage(pBitmap, 300, 300);

            free(pPalette);
            delete pBitmap;

            //draw with gdi
            {
                BITMAPINFO* pBmi = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);
                memset(pBmi, 0, sizeof(BITMAPINFO));
                BITMAPINFOHEADER &bmh = pBmi->bmiHeader;
                bmh.biSize = sizeof(BITMAPINFOHEADER);
                bmh.biBitCount = 8;
                bmh.biCompression = BI_RGB;
                bmh.biPlanes = 1;
                RGBQUAD* palette = &pBmi->bmiColors[0];
                for (int i = 0; i < 256; ++i) 
                {
                    RGBQUAD rgb = {0};
                    rgb.rgbRed =  ~i;
                    rgb.rgbGreen =  ~i;
                    rgb.rgbBlue =  ~i;
                    palette[i] = rgb;
                }
                bmh.biWidth = stride;
                bmh.biHeight =  - pBm->bitmap.rows;
                StretchDIBits(hdc, 200, 200, stride, pBm->bitmap.rows, 0, 0, stride, pBm->bitmap.rows, pBuffer, 
                    pBmi, DIB_RGB_COLORS, SRCCOPY);

                if (pBmi)
                    free(pBmi);

                if (pBuffer != pBm->bitmap.buffer)
                    delete [] pBuffer;

                /*bmh.biWidth = pBm->bitmap.width;
                bmh.biHeight =  - pBm->bitmap.rows;
                StretchDIBits(hdc, 200, 200, pBm->bitmap.width, pBm->bitmap.rows, 0, 0, pBm->bitmap.width, pBm->bitmap.rows, pBm->bitmap.buffer, 
                    pBmi, DIB_PAL_COLORS, SRCCOPY);*/
            }

        }
        EndPaint(hWnd, &ps);

两点:

1)正如马克·兰德森和paulsm4所说,调色板是必备的。

2)按4对齐。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14391938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档