Display a checkerboard background in transparent images.
Hello! 😊 JPEGview rocks! 💪 It is the fastest viewer I have seen on Windows, and I have tried a lot of them: W10 Photos, IrfanView, XnView, ImageGlass, etc.. I wonder if it would be possible to display a checkerboard background in transparent images.
For example, this transparent PNG image:

is shown in JPEGview:

Paint.net shows it in this way:

Would it be possible to display a checkerboard background in transparent images like the one in Paint.net image? Best Regards. 🙏
I'm not quite sure how to implement that change right now. Hopefully someone might direct me how to draw checkerboard instead of a single color on the canvas. But it's a nice suggested feature
JPEGView's CJPEGImage class does not seem to support alpha. ImageLoadThread.cpp pre-blends alpha into the RGB pixels, creating an opaque. So alpha data is kind of 'lost', and there's no convenient way to just change the background painted in OnPaint() to checkerboard, and just paint the transparent image over it thereafter. Like so:
- If CPEGImage can be enhanced to preserve alpha, create a custom checkerboard brush in lieu of
backBrushused inCMainDlg::OnPaint()to paint the background.- Like using CreateDIBPatternBrush or CreatePatternBrush? - not familiar with these.
- Or even just a hatch brush from CreateHatchBrush.
//pseudo code
LRESULT CMainDlg::OnPaint(...
...
CBrush backBrush;
backBrush.CreateSolidBrush(CSettingsProvider::This().ColorBackground());
CBrush hatchBrush;
hatchBrush.CreateHatchBrush(HS_CROSS, RGB(255, 0, 0)); //red
...
if (pDIBData != NULL) {
CPoint ptDIBStart = HelpersGUI::DrawDIB32bppWithBlackBorders(...,
bViewTransparency? hatchBrush: backBrush, ...);
...
}
//and change DrawDIB32bppWithBlackBorders to paint 1 big box for background instead of 4 border boxes.
//though will screen flash badly with animated image?
- See
WebpAlphaBlendBackground(pixel, backgroundColor)and its use inImageLoadThread.cpp.- JPEGView.ini has a setting
TransparencyColor=0 0 0for that backgroundColor. It appears to be in B G R format instead, not R G B as its comment says. - Alternatively, hack
WebpAlphaBlendBackgroundto take in each pixel's x & y position, and based on the positions, alternately use checkerboard colours for backgroundColor.- Con: Won't be able to toggle checkerboard on and off while viewing though (without image reload), since the checkerboard is blended in once, upon image load.
- JPEGView.ini has a setting
static inline uint32 WebpAlphaBlendBackground(uint32 pixel, uint32 backgroundColor, bool bCheckerboard = false, int x = 0, int y = 0)
{
uint32 alpha = pixel & 0xFF000000;
if (alpha == 0xFF000000)
{
return pixel;
}
if (bCheckerboard)
{
//ignore configured backgroundColor, and use white and light gray for checkerboard
if (((x & 0x10) && ((y & 0x10) == 0))
|| ((y & 0x10) && ((x & 0x10) == 0)))
{
backgroundColor = 0x00ffffff;
}
else
{
backgroundColor = 0x00c0c0c0;
}
}
if (alpha == 0) {
return backgroundColor;
}
else {
uint8 r = GetRValue(pixel);
uint8 g = GetGValue(pixel);
uint8 b = GetBValue(pixel);
uint8 bg_r = GetRValue(backgroundColor);
uint8 bg_g = GetGValue(backgroundColor);
uint8 bg_b = GetBValue(backgroundColor);
uint8 a = alpha >> 24;
uint8 one_minus_a = 255 - a;
return
0xFF000000 +
((uint8)(((r * a + bg_r * one_minus_a) / 255.0) + 0.5)) +
((uint8)(((g * a + bg_g * one_minus_a) / 255.0) + 0.5) << 8) +
((uint8)(((b * a + bg_b * one_minus_a) / 255.0) + 0.5) << 16);
}
}
void CImageLoadThread::ProcessReadPNGRequest(CRequest* request) { //also change for ProcessReadWEBPRequest()
...
//for (int i = 0; i < nWidth * nHeight; i++)
//*pImage32++ = WebpAlphaBlendBackground(*pImage32, CSettingsProvider::This().ColorTransparency());
for (int y = 0; y < nHeight; ++y)
for (int x = 0; x < nWidth; ++x)
*pImage32++ = WebpAlphaBlendBackground(*pImage32, CSettingsProvider::This().ColorTransparency(), true, x, y);
...
- Incidental issue: Unable to save an image with transparency - or rather the transparency is lost. The output image will Not have transparency. Its background will be default black.
CJPEGView looks super complicated to change.