Page 1 of 1

Howto Detect Bitmap Format

Posted: Sun May 18, 2008 7:41 pm
by toninhofwi
Hi,

How I do to detect a bitmap format (16bpp/32bpp) *after* I'd loaded it please?

Thanks and regards,

Toninho.

Posted: Mon May 19, 2008 8:17 am
by StefanHaupt
Toninho,

here you have a function to read all properties of a bitmap

Code: Select all

#define TAB Chr(9)

...
nH := FOpen (cBmp)
MsgInfo (BmpInfo (nH)
FClose (nH)
...

//-------------------------------------------------------------------//
FUNCTION BmpInfo (nH, cBmp)

  LOCAL i, cInfo := ""
  LOCAL aInfoText := {"Bitmaptype"+TAB+": ",;//       : ",;
                      "Size"+TAB+TAB+": ",;//             : ",;
                      "reserved"+TAB+TAB+": ",;//         :",;
                      "reserved"+TAB+TAB+": ",;//         :",;
                      "Data offset"+TAB+": ",;//      : ",;
                      "Header Size"+TAB+": ",;//      : ",;
                      "Width"+TAB+TAB+": ",;//            : ",;
                      "Height"+TAB+TAB+": ",;//           : ",;
                      "No planes"+TAB+": ",;//        : ",;
                      "Bits/pixel"+TAB+TAB+": ",;//       : ",;
                      "Compression"+TAB+": ",;//      : ",;
                      "Image Data size"+TAB+": ",;//  : ",;
                      "horz. pixel/meter"+TAB+": ",;//: ",;
                      "Vert. pixel/meter"+TAB+": ",;//: ",;
                      "No of colors"+TAB+": ",;//     : ",;
                      "Important colors"+TAB+": "  }

  aInfo := Array (20)

  IF nH > 0

    aInfo[1] := Chr (FReadByte (nH, 0, 1)) +;   // Typ
                Chr (FReadByte (nH, 1, 1))
    aInfo[2] := FReadByte (nH, 2,4)    // Filesize
    aInfo[3] := FReadByte (nH, 6,2)    // reserved, 0
    aInfo[4] := FReadByte (nH, 8,2)
    aInfo[5] := FReadByte (nH, 10,4)   // Data offset
    aInfo[6] := FReadByte (nH, 14,4)    // size of BitmapInfoHeader
    aInfo[7] := FReadByte (nH, 18,4)    // width
    aInfo[8] := FReadByte (nH, 22,4)    // height
    aInfo[9] := FReadByte (nH, 26,2)    // no of planes, must be 0
    aInfo[10] := FReadByte (nH, 28,2)   // no of bits / pixel
    aInfo[11] := FReadByte (nH, 30,4)   // compression type
    aInfo[12] := FReadByte (nH, 34,4)   // size of image dat in bytes, 0 when no compression
    aInfo[13] := FReadByte (nH, 38,4)   // horz. pixel / meter
    aInfo[14] := FReadByte (nH, 44,4)   // vert. pixerl / meter
    aInfo[15] := FReadByte (nH, 46,4)   // no of colors
    aInfo[16] := FReadByte (nH, 50,4)   // no of important colors
    //aInfo{17] := FReadByte (nH, 54,4)   //

    cInfo := cBmp+CRLF
    FOR i := 1 TO 16
      cInfo += aInfoText[i]+cValToChar (aInfo[i])+CRLF
    NEXT

  ENDIF

RETURN (cInfo)



//-------------------------------------------------------------------//
FUNCTION FReadByte (nH, nOffset, nLen, lHex)

  LOCAL i, cBuffer, xByte, nByte

  DEFAULT lHex := .f.  // return hex numbers

  FSeek (nH, nOffset, 0)
  cBuffer := Space (nLen)
  FRead (nH, @cBuffer, nLen)
  IF nLen = 4  // 32 bit
    nByte := Bin2L (cBuffer)
  ELSE
    nByte := Bin2I (cBuffer)
  ENDIF

  xByte := IIF (!lHex, nByte, Lower (DecToHex (nByte)) )
  IF lHex
    IF Len(xByte)<2
      xByte := "0"+xByte
    ENDIF
  ENDIF
  //? cByte, DecToHex (nByte), Len(cByte), Empty(cByte)

RETURN (xByte)

Posted: Mon May 19, 2008 11:09 am
by toninhofwi
Stefan, thanks for your help. Do you know if there are any way to use bitmap handle? Something like: GetBitmapFormat( oBmp:hBitmap ) ?

Regards,

Toninho.

Posted: Mon May 19, 2008 12:00 pm
by Antonio Linares
Toninho,

Try this:

Code: Select all

HB_FUNC( BMPFORMAT ) // hBitmap --> nBitsPixel
{
   BITMAP bm;

   GetObject( ( HBITMAP ) hb_parnl( 1 ), sizeof( BITMAP ), ( LPSTR ) &bm );

   hb_retnl( bm.bmBitsPixel );
}

Posted: Mon May 19, 2008 12:36 pm
by toninhofwi
Antonio Linares wrote:Toninho,

Try this:

Code: Select all

HB_FUNC( BMPFORMAT ) // hBitmap --> nBitsPixel
{
   BITMAP bm;

   GetObject( ( HBITMAP ) hb_parnl( 1 ), sizeof( BITMAP ), ( LPSTR ) &bm );

   hb_retnl( bm.bmBitsPixel );
}
Thanks Antonio, but this is the first thing that I´d tried and the bm.bmBitsPixel always return 32. If I go to the proprierties of the .bmp file in windows, I see 8 bits.

Maybe is because I load it by Resource ?

Very strange.

Regards,

Toninho.

Posted: Tue May 20, 2008 7:37 am
by StefanHaupt
toninhofwi wrote:Stefan, thanks for your help. Do you know if there are any way to use bitmap handle? Something like: GetBitmapFormat( oBmp:hBitmap ) ?
No, sorry. If Antonios function does not work, I have no solution.

Posted: Tue May 20, 2008 10:47 am
by Antonio Linares
Toninho,

Maybe we could try to check these struct members:

typedef struct tagBITMAPINFOHEADER{ // bmih
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;

Posted: Tue May 20, 2008 11:47 am
by toninhofwi
Antonio Linares wrote:Toninho,
Maybe we could try to check these struct members:
Thanks Antonio.

Is very strange but for loaded file images biBitCount works but for loaded *resources* it always return 32. I solve my problem create a new parameter for DEFINE BITMAP command, that now have a new option: ALPHABLEND.

---cut---
#xcommand REDEFINE BITMAP [ <oBmp> ] ;
[ ID <nId> ] ;
[ <of: OF, WINDOW, DIALOG> <oWnd> ] ;
[ <resource: NAME, RESNAME, RESOURCE> <cResName> ] ;
[ <file: FILE, FILENAME, DISK> <cBmpFile> ] ;
[ <lClick: ON ClICK, ON LEFT CLICK> <uLClick> ] ;
[ <rClick: ON RIGHT CLICK> <uRClick> ] ;
[ <scroll: SCROLL> ] ;
[ <adjust: ADJUST> ] ;
[ CURSOR <oCursor> ] ;
[ MESSAGE <cMsg> ] ;
[ <update: UPDATE> ] ;
[ WHEN <uWhen> ] ;
[ VALID <uValid> ] ;
[ <transparent: TRANSPARENT> ] ;
[ <alphablend: ALPHABLEND> ] ;
=> ;
[ <oBmp> := ] TBitmap():ReDefine( <nId>, <cResName>, <cBmpFile>,;
<oWnd>, [\{ |nRow,nCol,nKeyFlags| <uLClick> \}],;
[\{ |nRow,nCol,nKeyFlags| <uRClick> \}],;
<.scroll.>, <.adjust.>, <oCursor>, <cMsg>, <.update.>,;
<{uWhen}>, <{uValid}>, <.transparent.>, <.alphablend.> )
--cut---

Thanks and best regards.

PS: I only have problems now painting alphablended bitmaps in grayscale. Please see another topic that I´d created.

Posted: Tue May 20, 2008 11:51 am
by Antonio Linares
Toninho,

I see. Yes, its a good idea to add it for Class TBitmap, thanks! :-)

Switch from 'normal' BMP to ALPHABLEND

Posted: Tue May 20, 2008 2:09 pm
by ukoenig
I had a question in a topic a few days ago, about to swich from
alphablend to 'normal' BMP.
Would it be possible to have this solution with this extra parameter ?

Another idea was for the function :

Sample :
ABPaint( hDC, 5, 5, oBmp:hBitmap, 255 )

// Value 0-255 use < 0 > for non alpablended Bitmaps ?
// only 1 Function for the different Bitmap-types

ABPaint( hDC, 5, 5, oBmp:hBitmap, 0 )

Regards

Uwe

Posted: Tue May 20, 2008 2:22 pm
by Antonio Linares
Uwe,

Yes, this new clause will help us to select the right paint function to be called from Class TBitmap Method Paint()

Posted: Wed May 21, 2008 5:44 am
by Antonio Linares
Toninho,

I guess that what we really need is a way to programmatically detect if a bitmap has an alpha channel.

We are looking to build such function.

Posted: Wed May 21, 2008 6:37 am
by Antonio Linares
Toninho,

Well it seems that we go back to the first function :-)

Code: Select all

HB_FUNC( BMPALPHA ) // hBitmap --> lYesNo 
{ 
   BITMAP bm; 

   GetObject( ( HBITMAP ) hb_parnl( 1 ), sizeof( BITMAP ), ( LPSTR ) &bm ); 

   hb_retl( bm.bmBitsPixel == 32 ); 
}
But, do you say that all bitmaps return .T. ?

Posted: Wed May 21, 2008 6:41 am
by Antonio Linares
> But, do you say that all bitmaps return .T. ?

I answer myself: yes. Bitmaps without alpha channel are returning .T. also, and I am using DEFINE BITMAP ... FILENAME ...

We need to find another way to check it