Bug in HasAlpha()

User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Bug in HasAlpha()

Post 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
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: Bug in HasAlpha()

Post 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
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Bug in HasAlpha()

Post 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" )

 
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Bug in HasAlpha()

Post 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" )

 
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: Bug in HasAlpha()

Post by Enrico Maria Giordano »

What is the official way to load an image and to check for alpha channel without using classes?

EMG
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Bug in HasAlpha()

Post 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);
    }
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: Bug in HasAlpha()

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Bug in HasAlpha()

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Bug in HasAlpha()

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Bug in HasAlpha()

Post 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 );
}
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: Bug in HasAlpha()

Post 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
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Bug in HasAlpha()

Post by Antonio Linares »

The idea is:

lHasAlpha = ABPaint( hDC, nX, nY, hBitmap, nAlphaLevel )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Enrico Maria Giordano
Posts: 7355
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Contact:

Re: Bug in HasAlpha()

Post 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
Post Reply