c++buildergdi+vcl

How to prevent dithering when rendering a 24 bpp bitmap with GDI+?


In C++Builder, I have a small VCL application that creates a 100 x 100 pixel, 24 bpp Gdiplus::Bitmap and fills it with the default form background color (clBtnFace / COLOR_BTNFACE). A TPaintBox fills an area of 100 x 100 pixels with the same color on the left, renders the generated bitmap on the right and outputs the Gdiplus::Color components on the bottom.

Here's the code for the OnPaint event handler of the TPaintBox:

void __fastcall TForm1::PaintBox1Paint (TObject *Sender)
{
    Gdiplus::Color Color;
    Color.SetFromCOLORREF(GetSysColor(COLOR_BTNFACE));

    PaintBox1->Canvas->TextOut(0, 108, ColorToStr(Color));

    Gdiplus::SolidBrush Brush(Color);
    Gdiplus::Pen Pen(Gdiplus::Color::Black);

    Gdiplus::Bitmap Bitmap(100, 100, PixelFormat24bppRGB);

    if (Bitmap.GetLastStatus() == Gdiplus::Ok)
    {
        Gdiplus::Graphics g(&Bitmap);

        g.FillRectangle(&Brush, 0, 0, 100, 100);

        if (g.GetLastStatus() != Gdiplus::Ok)
            return;
    }
    else
        return;

    Gdiplus::Graphics g(PaintBox1->Canvas->Handle);

    g.FillRectangle(&Brush, 0, 0, 100, 100);
    g.DrawImage(&Bitmap, 100, 0);
    g.DrawRectangle(&Pen, 0, 0, 200, 100);
    g.DrawLine(&Pen, 100, 0, 100, 100);
}

When I run the application on my local PC, the areas on the left and right have a solid color (R: 224, G: 223, B: 227), exactly as output by the application.

When I run the application via a Remote Desktop connection with 16 bpp, the area on the left (rendered by Graphics::FillRectangle()) has a solid color. However, the area on the right (the bitmap rendered by Graphics::DrawImage()) is dithered, as shown in the screenshot below.

Screenshot

Here's what it looks like, when I zoom in:

Screenshot zoomed-in

When I save the generated Gdiplus::Bitmap on the remote PC to a .BMP file and open it in a photo editor, the bitmap contains a solid color (R: 224, G: 223, B: 227), exactly as output by the application. That means the generated bitmap is not dithered and the dithering must occur in the Graphics::DrawImage() call.

The form background color (clBtnFace / COLOR_BTNFACE) is in the 16 bpp color palette, otherwise the area on the left wouldn't be a solid color that exactly matches the color output by the application.

How do I prevent Graphics::DrawImage() using dithering when rendering the (full color) bitmap?


Solution

  • As pointed out in the comments, this is not dithering but a side effect of bitmap compression in RDP.