FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Alpha-Blended-BMP => the easy way
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Alpha-Blended-BMP => the easy way
Posted: Sun Mar 29, 2009 12:28 PM
Got it !!! :-)

Please add this function in FWH\source\winapi\dibbmp.c
Code (fw): Select all Collapse
CLIPPER HASALPHA( PARAMS ) // hBitmap --> lYesNo
{
   HANDLE hDib = DibFromBitmap( ( HBITMAP ) _parnl( 1 ), 0, 0, 
                                ( HPALETTE ) _parnl( 2 ) );
   BOOL bAlphaChannel = FALSE;
            
   if( hDib )
   {
      LPBITMAPINFO lpbmi = ( LPBITMAPINFO ) GlobalLock( hDib );
      unsigned char * uc = ( LPBYTE ) lpbmi + ( WORD ) lpbmi->bmiHeader.biSize + PaletteSize( lpbmi );
      unsigned long ul;

      for( ul = 0; ul < lpbmi->bmiHeader.biSizeImage; ul += 4 )
         if( uc[ ul + 3 ] != 0 )
            bAlphaChannel = TRUE;    

      GlobalUnlock( hDib );
   }
   
   _retl( bAlphaChannel );
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Alpha-Blended-BMP =&gt; the easy way
Posted: Sun Mar 29, 2009 12:41 PM
Here you have a self contained working example. I appreciate your feedback testing different bitmaps with/without alpha channel, thanks! :-)

test.prg
Code (fw): Select all Collapse
#include "FiveWin.ch"

function Main()

   local oBmp

   // DEFINE BITMAP oBmp FILENAME "c:\fwh\bitmaps\arrow.bmp" // No alpha

   DEFINE BITMAP oBmp FILENAME "c:\fwh\bitmaps\AlphaBmp\world.bmp" // with alpha

   MsgInfo( HasAlpha( oBmp:hBitmap ) )

   oBmp:End()

return nil

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>

WORD DibNumColors( void * pv );
HANDLE DibFromBitmap( HBITMAP, DWORD, WORD, HPALETTE );

static WORD PaletteSize( void * pv )
{
    LPBITMAPINFOHEADER lpbi = ( LPBITMAPINFOHEADER ) pv;
    WORD NumColors = DibNumColors( lpbi );

    if( lpbi->biSize == sizeof( BITMAPCOREHEADER ) )
       return ( WORD )( NumColors * sizeof( RGBTRIPLE ) );
    else
       return ( WORD )( NumColors * sizeof( RGBQUAD ) );
}

HB_FUNC( HASALPHA ) // hBitmap --> lYesNo
{
   HANDLE hDib = DibFromBitmap( ( HBITMAP ) hb_parnl( 1 ), 0, 0, 
                                ( HPALETTE ) hb_parnl( 2 ) );
   BOOL bAlphaChannel = FALSE;
            
   if( hDib )
   {
      LPBITMAPINFO lpbmi = ( LPBITMAPINFO ) GlobalLock( hDib );
      unsigned char * uc = ( LPBYTE ) lpbmi + ( WORD ) lpbmi->bmiHeader.biSize + PaletteSize( lpbmi );
      unsigned long ul;

      for( ul = 0; ul < lpbmi->bmiHeader.biSizeImage; ul += 4 )
         if( uc[ ul + 3 ] != 0 )
            bAlphaChannel = TRUE;    

      GlobalUnlock( hDib );
   }
   
   hb_retl( bAlphaChannel );
}         

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Alpha-Blended-BMP =&gt; the easy way
Posted: Sun Mar 29, 2009 01:40 PM
Congratulations that you finally got it.
Here is a small program using the above code to check all bitmap files in any selected folder and show which bitmaps have alpha channel and which do not.
Code (fw): Select all Collapse
#include "FiveWin.ch"

function Main()

   local cDir  := cGetDir( "Bitmap Directory", "c:\fwh\bitmaps" )
   local aDir, aAlpha   := {}
   local n, oBmp

   aDir     := Directory( cDir + "\*.bmp" )
   aEval( aDir, { |a| AAdd( aAlpha,  { cDir + "\" + a[ 1 ], "no alpha" } ) } )

   for n := 1 to Len( aAlpha )
      DEFINE BITMAP oBmp FILENAME aAlpha[ n ][ 1 ]
      if HasAlpha( oBmp:hBitmap )
         aAlpha[ n ][ 2 ]  := "HAS ALPHA"
      endif
      oBmp:End()
   next n
   xbrowse( aAlpha, cDir )


return nil


#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>

WORD DibNumColors( void * pv );
HANDLE DibFromBitmap( HBITMAP, DWORD, WORD, HPALETTE );

static WORD PaletteSize( void * pv )
{
    LPBITMAPINFOHEADER lpbi = ( LPBITMAPINFOHEADER ) pv;
    WORD NumColors = DibNumColors( lpbi );

    if( lpbi->biSize == sizeof( BITMAPCOREHEADER ) )
       return ( WORD )( NumColors * sizeof( RGBTRIPLE ) );
    else
       return ( WORD )( NumColors * sizeof( RGBQUAD ) );
}

HB_FUNC( HASALPHA ) // hBitmap --> lYesNo
{
   HANDLE hDib = DibFromBitmap( ( HBITMAP ) hb_parnl( 1 ), 0, 0,
                                ( HPALETTE ) hb_parnl( 2 ) );
   BOOL bAlphaChannel = FALSE;

   if( hDib )
   {
      LPBITMAPINFO lpbmi = ( LPBITMAPINFO ) GlobalLock( hDib );
      unsigned char * uc = ( LPBYTE ) lpbmi + ( WORD ) lpbmi->bmiHeader.biSize + PaletteSize( lpbmi );
      unsigned long ul;

      for( ul = 0; ul < lpbmi->bmiHeader.biSizeImage; ul += 4 )
         if( uc[ ul + 3 ] != 0 )
            bAlphaChannel = TRUE;

      GlobalUnlock( hDib );
   }

   hb_retl( bAlphaChannel );
}


#pragma ENDDUMP

Compile run and see the results in xbrowse for all bitmaps
Regards



G. N. Rao.

Hyderabad, India
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Alpha-Blended-BMP =&gt; the easy way
Posted: Mon Mar 30, 2009 12:50 AM

We can optimize HasAlpha() this way:

  for( ul = 0; ul &lt; lpbmi-&gt;bmiHeader.biSizeImage &amp;&amp; ! bAlphaChannel; ul += 4 )

so there is no need to step through the whole array of bytes, once we find one that matches what we are looking for :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 1335
Joined: Fri Jun 13, 2008 11:04 AM
Re: Alpha-Blended-BMP =&gt; the easy way
Posted: Mon Mar 30, 2009 05:20 AM

Dear Mr.Antonio & Mr.Nageshwara Rao,

I have tested my Application's Images folder wich contains BMP's with and without AlphaChannels and the new function HasAlpha is working perfectly.

I tried to upload a screen snapshot using Imageshack but right now here unable to upload using ImageShack. Don't know the reason. After browsing the pic and click upload, ImageShack say's "no files uploaded"

Anyway HasAlpha is working perfectly

Regards

Anser

Continue the discussion