FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index Bugs report & fixes / Informe de errores y arreglos Bug in HasAlpha()
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Bug in HasAlpha()
Posted: Sat Apr 01, 2017 12:16 PM

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

Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Re: Bug in HasAlpha()
Posted: Sat Apr 01, 2017 01:17 PM
This is a sample:

Code (fw): Select all Collapse
#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
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Bug in HasAlpha()
Posted: Tue Apr 04, 2017 10:16 PM
Try with

Code (fw): Select all Collapse
#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" )
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Bug in HasAlpha()
Posted: Tue Apr 04, 2017 10:22 PM
Another possibility

Code (fw): Select all Collapse
#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" )
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 08:09 AM

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

EMG

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 08:18 AM
This is an interesting reading and this code may be the simplest way to do it:

https://www.gamedev.net/topic/607214-get-alpha-channel-from-32bit-bmp/

Code (fw): Select all Collapse
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
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 08:26 AM

Thank you. I will wait for something faster. I'm going to drop alpha channel support in my application, for the moment.

EMG

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 08:30 AM

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
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 09:19 AM
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/library/windows/desktop/dd183351(v=vs.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
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 09:31 AM

Ok, let's try it.

EMG

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 10:01 AM
Please try it using this function:

You have to provide it a hDC and later on call DeleteDC()

Code (fw): Select all Collapse
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
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 10:24 AM

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

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 10:33 AM

The idea is:

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

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 9020
Joined: Thu Oct 06, 2005 08:17 PM
Re: Bug in HasAlpha()
Posted: Wed Apr 05, 2017 11:17 AM

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