1

I'm working on a VCL Windows desktop application using C++Builder 10.2 Tokyo.

I have the following to try to read out pixels from a TBitmap object in order to make further pixel-based manipulations. However, even though the codes recognizes 32bit format correctly and creates the bitmap image accordingly, I couldn't read out correct pixel info using TBitmap::ScanLine.

The image used is not black, but the RGB values read from pBMP are all of zero and Alpha values are 6, 17, 34, ect. which seems as corrupted or uninitialized data.

//given png image saved as application resource
std::unique_ptr<TResourceStream> pRes(new TResourceStream(
        reinterpret_cast<NativeUInt>(HInstance),
        L"a_png_resource_name",
        RT_RCDATA));
std::unique_ptr<TPngImage> pPNG(new TPngImage());
pPNG->LoadFromStream(pRes.get());

std::unique_ptr<TBitmap> pBMP(new TBitmap());
pBMP->Assign(pPNG.get());
pBMP->SaveToFile(L"resulting_image.bmp"); //it creates bmp with correct RGBA content 
assert(pBMP->PixelFormat == pf32bit); //just confirm we have correct format to access pixels
for (int i = 0; i < pBMP->Height; i++) {
  Pixel* FirstPixelInLine = (Pixel*)pBMP->ScanLine[i];
  for (int j = 0; j < pBMP->Width; j++) {
    Pixel* p = FirstPixelInLine + j;
    OutputDebugString((L"R: " + std::to_wstring(p->Red) +
    L" G: " + std::to_wstring(p->Green) +
    L" B: " + std::to_wstring(p->Blue) +
    L" A: " + std::to_wstring(p->Alpha)).c_str());
  }
}

And the definition of Pixel is as follows:

struct Pixel {
  BYTE Blue;
  BYTE Green;
  BYTE Red;
  BYTE Alpha;
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
smags
  • 33
  • 4
  • hmm that should work my guess is you got align problem what is the `sizeof(pixel)` if not `4` than either use [`#pragma pack(1)`](https://stackoverflow.com/a/36467401/2521214) for the `pixel` struct or `DWORD*` or `BYTE*` instead of `pixel*` – Spektre Mar 01 '18 at 07:24
  • hmm, I checked the possible alignment issue and sizeof yield 4. And with 4 BYTEs defined in the structure, it seems to it all looks good in term of alignment. – smags Mar 01 '18 at 17:43
  • The Win32 API has an [`RGBQUAD`](https://msdn.microsoft.com/en-us/library/windows/desktop/dd162938.aspx) struct. You should be using that instead of your custom `Pixel` struct. Aside from that, I don't see any other problems with this code. – Remy Lebeau Mar 01 '18 at 22:11
  • 1
    Related? https://stackoverflow.com/q/22291162 – Jongware Mar 01 '18 at 22:21
  • Did you actually check that `pBMP->Height` and `pBMP->Width` return correct values? Just because `pBMP->SaveToFile` works as expected still doesn't mean that all properties are set correctly. – dsp_user Mar 02 '18 at 07:49
  • 1
    It turns out the coding in the question is fine. What is messed up is TBitmap::Assign is not actually called in the real codebase. Thank you all for the comments and thank you Remy for the heads up about RGBQUAD structure. – smags Mar 02 '18 at 22:54

0 Answers0