On approximately 7/11/2004 6:26 AM, came the following characters from
the keyboard of Pavel:

Hello

Is it possible to create Win32::GUI::Bitmap object not from file, but
from memory data? Or how can I add bitmap to ImageList direct from
memory data?

something like:

# $img is a content of one.bmp file
my $b = Win32::GUI::Bitmap::Create(16,16,0,24,$img);  # dont works
$IL->Add($b);

thanks

Maybe the following subs will come in handy: If your window is wide enough, you shouldn't have line wrapping problems, but be careful. Note that I'm getting my BMP from ImageMagick conversion to BMP Blobs; if your BMPs come from elsewhere, you may need to modify this code somewhat.

#####################################
# sub BitmapFromBMPBuffer  # version 2003/03/11

use Win32::GUI ();

sub BitmapFromBMPBuffer
{ my ( $mw, $bmp ) = @_;
  my ( $bitmap );
  my ( $hWnd ) = $mw->{'-handle'};
  my ( $hBitmap ) = & HBITMAPFromBMPBuffer ( $hWnd, $bmp );
  if ( $hBitmap )
  { $bitmap = { -handle => $hBitmap };
    bless $bitmap, 'Win32::GUI::Bitmap';
  }
  return $bitmap;
}
#####################################
# sub HBITMAPFromBMPBuffer  # version 2003/03/11

#% use Win32::GUI ();

# code to convert bitmap-in-$bmp to a Win32::GUI::Bitmap object
sub HBITMAPFromBMPBuffer
{ my ( $hWnd, $bmp ) = @_;

# typedef struct tagBITMAPFILEHEADER { // bmfh
#     WORD    bfType; // "BM"
#     DWORD   bfSize; // size of whole bitmap (file)
#     WORD    bfReserved1; // zero
#     WORD    bfReserved2; // zero
#     DWORD   bfOffBits; // offset to bitmap bits
# } BITMAPFILEHEADER; // 14 bytes total
#
# typedef struct tagBITMAPINFOHEADER{ // bmih
#     DWORD  biSize; // size of header structure
#     LONG   biWidth; // pixel width of bitmap
#     LONG   biHeight; // pixel height of bitmap, if negative is top down
#     WORD   biPlanes; // one
#     WORD   biBitCount; // bits per pixel: 0 (JPEG), 1, 4, 8, 16, 24, or 32
# DWORD biCompression; // BI_RGB, BI_RLE8, BI_RLE4, BI_BITFIELDS, BI_JPEG
#     DWORD  biSizeImage; // size in bytes of bitmap bits
#                         // may be 0 for BI_RGB, since it is calculable
#                         // biWidth * biBitCount rounded to 32, * biHeight
#     LONG   biXPelsPerMeter; // horizontal pixels per meter
#     LONG   biYPelsPerMeter; // vertical pixels per meter
#     DWORD  biClrUsed; // number of colors in color map
#                       // 0 => 2^biBitCount
#     DWORD  biClrImportant; // number of important colors, 0 => biClrUsed
# } BITMAPINFOHEADER; // 40 bytes
#
# /* constants for the biCompression field */
#define BI_RGB        0L
#define BI_RLE8       1L
#define BI_RLE4       2L
#define BI_BITFIELDS  3L
#
# Note that ImageMagick produced BMP images have all the details filled in,
# no might-be-zero fields to deal with.

# Need to unpack offBits, biHeight, and biWidth for use in BITMAP creation API # calls, and also to split the data at 14 and at offBits so the pieces can be
# passed using Win32::API.  Also, biHeight and biWidth will be useful for
# figuring out screen/window dimensions, perhaps.

  my ( @bmphdr ) = unpack ( 'vVvvV VVV', $bmp );
  my ( $magic, $offBits, $biWidth, $biHeight ) = @bmphdr[ 0, 4, 6, 7 ];
  my ( $bmfh ) = substr ( $bmp, 0, 14 );
  my ( $bmDIBh ) = substr ( $bmp, 14, $offBits - 14 );
  my ( $bmBits ) = substr ( $bmp, $offBits );

  if ( $magic != 0x4d42 )
  { demise "Bad magic ( $magic ), should be 'BM'\n";
  }

  my ( $bmhand, $hdc, $hcdc, $res );
  $hdc = & gGetDC ( $hWnd );
  demise "Bad res from GetDC: $^E\n"  unless $hdc;
  $bmhand = & gCreateCompatibleBitmap ( $hdc, $biWidth, $biHeight );
  demise "Bad res from CreateCompatibleBitmap: $^E\n"  unless $bmhand;
  $res = & gSetDIBits ( $hdc, $bmhand, 0, $biHeight, $bmBits, $bmDIBh, 0 );
  demise "Bad res from SetDIBits: $^E\n"  unless $res;
  $res = & gReleaseDC ( $hWnd, $hdc );
  demise "Bad res from ReleaseDC: $^E\n"  unless $res;
  return $bmhand;
}

--
Glenn -- http://nevcal.com/
===========================
The best part about procrastination is that you are never bored,
because you have all kinds of things that you should be doing.


Reply via email to