Bug in HasAlpha()

Bug in HasAlpha()

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

Re: Bug in HasAlpha()

Postby Enrico Maria Giordano » Sat Apr 01, 2017 1:17 pm

This is a sample:

Code: Select all  Expand view
#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
Enrico Maria Giordano
 
Posts: 8713
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia


Re: Bug in HasAlpha()

Postby cnavarro » Tue Apr 04, 2017 10:16 pm

Try with

Code: Select all  Expand view


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

Re: Bug in HasAlpha()

Postby cnavarro » Tue Apr 04, 2017 10:22 pm

Another possibility

Code: Select all  Expand view


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

Re: Bug in HasAlpha()

Postby Enrico Maria Giordano » Wed Apr 05, 2017 8:09 am

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

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

Re: Bug in HasAlpha()

Postby Antonio Linares » Wed Apr 05, 2017 8: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: Select all  Expand view
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
Antonio Linares
Site Admin
 
Posts: 42097
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Bug in HasAlpha()

Postby Enrico Maria Giordano » Wed Apr 05, 2017 8: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
User avatar
Enrico Maria Giordano
 
Posts: 8713
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Bug in HasAlpha()

Postby Antonio Linares » Wed Apr 05, 2017 8: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42097
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Bug in HasAlpha()

Postby Antonio Linares » Wed Apr 05, 2017 9: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42097
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Re: Bug in HasAlpha()

Postby Antonio Linares » 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: Select all  Expand view
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
Antonio Linares
Site Admin
 
Posts: 42097
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Bug in HasAlpha()

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

Re: Bug in HasAlpha()

Postby Antonio Linares » Wed Apr 05, 2017 10:33 am

The idea is:

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

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

Re: Bug in HasAlpha()

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

Next

Return to Bugs report & fixes / Informe de errores y arreglos

Who is online

Users browsing this forum: No registered users and 1 guest