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.