Page 1 of 2
Bug in HasAlpha()
Posted: Sat Apr 01, 2017 12:16 pm
by Enrico Maria Giordano
The function HasAlpha doesn't work anymore. It returns .T. even if the image doesn't have an alpha channel. I noticed that the function has been changed in dibbmp.c, don't know exactly when.
EMG
Re: Bug in HasAlpha()
Posted: Sat Apr 01, 2017 1:17 pm
by Enrico Maria Giordano
This is a sample:
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
LOCAL hBmp := LOADIMG( "c:\fwh\bitmaps\olga1.jpg" )
? hBmp
? HASALPHA( hBmp )
RETURN NIL
FUNCTION LOADIMG( cFile )
IF !FILE( cFile )
RETURN 0
ENDIF
IF UPPER( CFILEEXT( cFile ) ) = "BMP"
RETURN READBITMAP( 0, cFile )
ENDIF
RETURN GDIP_IMAGEFROMFILE( cFile, .T., UPPER( CFILEEXT( cFile ) ) = "GIF" )
Any ideas?
EMG
Re: Bug in HasAlpha()
Posted: Tue Apr 04, 2017 2:28 pm
by Enrico Maria Giordano
Up!
EMG
Re: Bug in HasAlpha()
Posted: Tue Apr 04, 2017 10:16 pm
by cnavarro
Try with
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
local cFile := "d:\fwh\fwhteam\bitmaps\olga1.jpg"
local hBmp := LoadImg( cFile )
? hBmp, HASALPHA( hBmp )
? GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ), ;
( GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ) = 0 )
cFile := "D:\Fwh\FwhTeam\bitmaps\AlphaBmp\android.bmp"
hBmp := LoadImg( cFile )
? hBmp, HASALPHA( hBmp )
? GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ), ;
( GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ) = 0 )
Return NIL
//----------------------------------------------------------------------------//
FUNCTION LoadImg( cFile )
IF !FILE( cFile )
RETURN 0
ENDIF
IF UPPER( CFILEEXT( cFile ) ) = "BMP"
RETURN READBITMAP( 0, cFile )
ENDIF
Return GDIP_IMAGEFROMFILE( cFile, .T., UPPER( CFILEEXT( cFile ) ) = "GIF" )
Re: Bug in HasAlpha()
Posted: Tue Apr 04, 2017 10:22 pm
by cnavarro
Another possibility
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
local oBmp
local cFile := "d:\fwh\fwhteam\bitmaps\olga1.jpg"
local hBmp := LoadImg( cFile )
? hBmp, HASALPHA( hBmp )
? GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ), ;
( GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ) = 0 )
cFile := "D:\Fwh\FwhTeam\bitmaps\AlphaBmp\android.bmp"
hBmp := LoadImg( cFile )
? hBmp, HASALPHA( hBmp )
? GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ), ;
( GdiplusImagePixGetAlpha( GdiPlusImageLoadCachedFile( cFile ) ) = 0 )
cFile := "d:\fwh\fwhteam\bitmaps\olga1.jpg"
oBmp := GdiBmp():New( cFile )
? oBmp:IsAlphaChannel(), oBmp:Is32Bits()
oBmp:Destroy()
cFile := "D:\Fwh\FwhTeam\bitmaps\AlphaBmp\android.bmp"
oBmp := GdiBmp():New( cFile )
? oBmp:IsAlphaChannel(), oBmp:Is32Bits()
oBmp:Destroy()
Return NIL
//----------------------------------------------------------------------------//
FUNCTION LoadImg( cFile )
IF !FILE( cFile )
RETURN 0
ENDIF
IF UPPER( CFILEEXT( cFile ) ) = "BMP"
RETURN READBITMAP( 0, cFile )
ENDIF
Return GDIP_IMAGEFROMFILE( cFile, .T., UPPER( CFILEEXT( cFile ) ) = "GIF" )
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 8:09 am
by Enrico Maria Giordano
What is the official way to load an image and to check for alpha channel without using classes?
EMG
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 8:18 am
by Antonio Linares
This is an interesting reading and this code may be the simplest way to do it:
https://www.gamedev.net/topic/607214-ge ... 32bit-bmp/
Code: Select all
struct ABGRStruct {
BYTE a,b,g,r;
};
FILE *f = fopen("the_file_name.bmp", "rb");
if(f){
int w, h;
fseek(f, 0x12, SEEK_SET);
fread(&w, 1, sizeof(int), f);
fread(&h, 1, sizeof(int), f);
fseek(f, 54, SEEK_SET);
int NumPixels = w * h;
for(int i = 0; i < NumPixels; i++){
ABGRStruct Pixel;
fread(&Pixel, 1, 4, f);
// do something with alpha
}
fclose(f);
}
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 8:26 am
by Enrico Maria Giordano
Thank you. I will wait for something faster. I'm going to drop alpha channel support in my application, for the moment.
EMG
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 8:30 am
by Antonio Linares
BitBlt() is the fastest way to manage bitmaps
Not sure if there is a flag we could used for Alpha channel detection
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 9:19 am
by Antonio Linares
Enrico,
Windows function AlphaBlend() returns a logical value once it tries to paint a bitmap that have transparent or semitransparent pixels:
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Thus, we could modify FWH function ABPaint() to return the return value of the AlphaBlend() call there
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 9:31 am
by Enrico Maria Giordano
Ok, let's try it.
EMG
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 10:01 am
by Antonio Linares
Please try it using this function:
You have to provide it a hDC and later on call DeleteDC()
Code: Select all
HB_FUNC( ABPAINT )
{
#ifdef _WIN64
HDC hDC = ( HDC ) hb_parnll( 1 );
#else
HDC hDC = ( HDC ) hb_parnl( 1 );
#endif
HDC hDCComp = CreateCompatibleDC( hDC );
BITMAP bm;
HGDIOBJ hOldBmp = SelectObject( hDCComp, ( HBITMAP ) fw_parH( 4 ) );
BLENDFUNCTION blend;
int wDest, hDest;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = IF( hb_parnl( 5 ) != 0, hb_parnl( 5 ), 220 );
blend.AlphaFormat = AC_SRC_ALPHA;
#ifdef _WIN64
GetObject( ( HBITMAP ) hb_parnll( 4 ), sizeof( BITMAP ), ( LPSTR ) &bm );
#else
GetObject( ( HBITMAP ) hb_parnl( 4 ), sizeof( BITMAP ), ( LPSTR ) &bm );
#endif
wDest = bm.bmWidth;
hDest = bm.bmHeight;
if( hb_pcount() > 5 )
{
wDest = hb_parni( 6 );
hDest = hb_parni( 7 );
}
hb_retl( AlphaBlend( hDC, hb_parnl( 2 ), hb_parnl( 3 ), wDest, hDest, hDCComp,
0, 0, bm.bmWidth, bm.bmHeight, blend ) );
SelectObject( hDCComp, hOldBmp );
DeleteDC( hDCComp );
}
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 10:24 am
by Enrico Maria Giordano
I don't understand. I have to select the correct painting function to use after checking for alpha channel. Ie:
IF HASALPHA()
use ABPAINT()
ELSE
use something else
ENDIF
EMG
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 10:33 am
by Antonio Linares
The idea is:
lHasAlpha = ABPaint( hDC, nX, nY, hBitmap, nAlphaLevel )
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 11:17 am
by Enrico Maria Giordano
Yes, but then the image is already printed with the right or wrong function. We need of a checking function that doesn't print the image, I think.
EMG