0

The following code,adopted from here, flips and paints a TBitmap on a TPaintbox.

void flipImageVertically(Graphics::TBitmap *pBitmap, TPaintBox* paintBox)
{
    int w = pBitmap->Width;
    int h = pBitmap->Height;
    TRect dest(getStretchedDimensions(w, h, paintBox->Width, paintBox->Height));

    TRect src(Rect(0, h, w, 0));

    Graphics::TBitmap *bmp;
    bmp = new TBitmap;
    bmp->PixelFormat = pBitmap->PixelFormat;
    bmp->SetSize(w,h);

    bmp->Canvas->Draw(0, 0, pBitmap);
    paintBox->Canvas->CopyRect(dest, bmp->Canvas, src);
    delete bmp;
}

However, compared to the code that just paints and stretches an image to the paintbox:

    TRect stretchedRect(getStretchedDimensions(tbm->Width, tbm->Height, paintBox->Width, paintBox->Height));
    paintBox->Canvas->StretchDraw(stretchedRect, tbm);

the flipped image have 'gleaming', looking over saturated pixels. I believe it has todo with the

    bmp->Canvas->Draw(0, 0, pBitmap);
    paintBox->Canvas->CopyRect(dest, bmp->Canvas, src);

lines of code, that don't involve a 'stretched' draw.

Trying changing the above code to using a stretched draw:

    paintBox->Canvas->StretchDraw(dest, bmp);

instead of CopyRect don't work. It still shows gleaming pixels and it is not flipped. (Just realized the above code flips the image horizontally). The bitmap is a 8bit greyscale bitmap.

Original: enter image description here

Flipped: enter image description here

Update Changing the pixel format to pf32Bit does fix most of the problems. However, when stretched to a smaller than original dimension, black 'squares' and other patterns emerge on various part of the image. See below:

enter image description here

Totte Karlsson
  • 1,261
  • 1
  • 20
  • 55
  • any screenshots and or MCVE of the problem? `CopyRect` cause problems if the `PixelFormat` is changing and or not true/hi-color see [Wrong color when using CopyRect to copy from large image to smaller canvas](https://stackoverflow.com/a/47710272/2521214) – Spektre Jan 31 '20 at 09:47
  • I can not reproduce the error you describe as 'gleaming', over saturated pixels, but I do see that you are missing the copy mode setting before calling `CopyRect`. Add ` paintBox->Canvas->CopyMode = SRCCOPY;` before you call `CopyRect`. You also speculated about `CopyRect()` not involving stretched draw. But rest assured, `CopyRect()` calls internally the `Winapi.StretchBlt()` function. – Tom Brunberg Jan 31 '20 at 10:01
  • @Tom-Brunberg Adding the Copymode revealed that the previous copying was not working properly. However, the gleaming pixels still remains unfortunately. – Totte Karlsson Jan 31 '20 at 18:06
  • @Spektre My bitmaps are all 8bits and not changing. I guess its the order of operations in my code causing the problem. Along with showing the bitmaps on the screen, the bitmap stream is also piped into a background ffmpeg process. I use ffmpegs features to flip the image, and I don't see the problem in the final video. – Totte Karlsson Jan 31 '20 at 18:36
  • @TotteKarlsson hmm that is not a screenshot but a photo instead (adding noise and other stuff to it) so you mean the problem is different shading of the white background? That is because you used `PixelFormat=pf8bit` that is indexed color palette and VCL `CopyRect` has poor support of it the solution is to either flip/rescale on your own using `ScanLine[]` property or switch to `pf32bit` see related: [simple fast dithering](https://stackoverflow.com/a/36820654/2521214) and [better color quantization then VCL/GDI](https://stackoverflow.com/a/30265253/2521214) – Spektre Feb 01 '20 at 08:29
  • @TotteKarlsson to reproduce this for us we need the input and for comparison also "wrong" output image . As you use bmp so simply make them with `bmp->SaveToFile("filename.bmp");` and share. Then create "small" chunk of code that starts with `bmp->LoadFromFile("filename.bmp")` do your `CopyRect` and either output to `Form1->Canvas` or save output to file. – Spektre Feb 02 '20 at 09:21
  • @Spektre Actually the above images are screenshoots. My streaming camera is capturing my screen. Your suggestion using pf32Bit does fix most of the issues. However, even when using the pf32Bit flag, the image gets 'funky' squares when stretched to a small dimension. I'll post a screenshot for that. I believe the best may be to manipulate the pixels myself, as you suggested using the ScanLine property. – Totte Karlsson Feb 07 '20 at 01:39

0 Answers0