Mask generation w/ colorkey

Whatisaspacebar
09-09-2004, 05:34 PM
Heya.

What would you do if you wanted to take, say, an ordinary 32-bit bitmap file, and create/output a mask to a seperate bitmap file using a specified colorkey for the mask? Would you use GetPixel API, GetBitmapBits, etc.?

I would make a function simular to the following psuedo-code:
Function CreateMask(FileSrc As String, FileDest As String, Optional ColorKey as RGBQUAD) As Boolean
'1.) Open source file, collect bits
'2.) Iterate through bits, recieving pixel colors one by one
'3.) If current pixel color is equal to ColorKey, create a white pixel
'Otherwise, create a black pixel. Copy that pixel into destination bit array.
'4.) Create a new bitmap using the completed destination array. Save it
'into the destination file.
'5.) Return True
End Function

Start talking. ;)

pikzel_R
09-09-2004, 05:43 PM
Heya.
What would you do if you wanted to take, say, an ordinary 32-bit bitmap file, and create/output a mask to a seperate bitmap file using a specified colorkey for the mask? Would you use GetPixel API, GetBitmapBits, etc.?
Start talking. ;)
For design time mask generation have you tried rpgnewbie's "AutoSpritemaskCreator2" program?
It's attached to this post:
http://www.xtremevbtalk.com/showpost.php?p=506109&postcount=11

After you run the program, the top command button is just for demo (to show how it works), so use the bottom command button and it will let you select your own bitmap to have a mask created for. The new mask file will have a "_msk" appended to it. After you select the file to be masked, the form that pops up will let you see (test) what your bitmap combined with mask looks like against a checkboard background.

The color key used is the color of the pixel in the far upper left corner (1,1)

OnErr0r
09-09-2004, 06:02 PM
I think I'd opt to create masks at runtime with the wrapper I posted (Code Library), or just use TransparentBlt, if your OS doesn't suffer from the memory leak.

pikzel_R
09-09-2004, 06:11 PM
I think I'd opt to create masks at runtime with the wrapper I posted (Code Library), or just use TransparentBlt, if your OS doesn't suffer from the memory leak.

Some people have complained that programmatic masking decreases the rendering speed of their program.

However, I have also posted a programmatic masking demo, attached to this post:
http://www.xtremevbtalk.com/showpost.php?p=824219

It's based on a Microsoft article:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;187568

Noi_Max's Wintermint engine also uses programmatic masking if you are looking for additional examples...

OnErr0r
09-09-2004, 06:18 PM
Some people have complained that programmatic masking decreases the rendering speed of their program.

However, I have also posted a programmatic masking demo, attached to this post:
http://www.xtremevbtalk.com/showpost.php?p=824219

It's based on a Microsoft article:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;187568

Noi_Max's Wintermint engine also uses programmatic masking if you are looking for additional examples...

The masking I'm using is cached. So the mask is only generated once. I'll take a look at that post here on the board. Thanks. :)

pikzel_R
09-09-2004, 06:44 PM
The masking I'm using is cached. So the mask is only generated once. I'll take a look at that post here on the board. Thanks. :)

Oh, you have a new example. I thought you were talking about that old example that used a res file, an 8 bit DIB, and 6 Bitblt's. I'll have to check it out...

Here's OnErr0r's cached programmatic masking post in the Code Library:
http://www.xtremevbtalk.com/showpost.php?p=505696

Whatisaspacebar
09-09-2004, 09:52 PM
Out of boredom, I created a sample program myself. It's attached to this post, so tell me what yall think.

BTW... Since I felt lazy, I forgot to add comments to this project. On top of that, the third PictureBox (which is supposed to display the resulted transparent blitted image) is cracked out. The rest of the code is the key part of this sample anyways.

This code could easily be modified to save the results to a file.

EDIT: Attachment updated. It now contains some comments, as well as a new function that allows an array of colors to be specified as the colorkey. I felt bad about slapping everything all together in 2 seconds, so I figured this was the least I could do.

pikzel_R
09-09-2004, 10:05 PM
Out of boredom, I created a sample program myself. It's attached to this post, so tell me what yall think.
I always say the forum could use a few more examples of bitblt masking, but I'm curious...does this have anything to do with the engine you are working on? --

"I know that this is mainly a VB forum (hence the URL, lol), but all I want to do is use an [out,retval] attribute to access the same DirectX objects that my engine (currently under development) uses from other languages such as VB6 (which i'm more experienced with)"
http://www.xtremevbtalk.com/showpost.php?p=819052

To Whatisaspacebar: I didn't want to bump this thread, but thanks for the reply and the update..

Whatisaspacebar
09-10-2004, 05:14 PM
I always say the forum could use a few more examples of bitblt masking, but I'm curious...does this have anything to do with the engine you are working on? --

"I know that this is mainly a VB forum (hence the URL, lol), but all I want to do is use an [out,retval] attribute to access the same DirectX objects that my engine (currently under development) uses from other languages such as VB6 (which i'm more experienced with)"
http://www.xtremevbtalk.com/showpost.php?p=819052
lol, no. That is an actual project that I've been doing in C++ using DirectX 8.1, and it has nothing to do with this. In fact, one reason I've been messing around with bltbit is because I'm vacationing away from that project at the moment. =P

My previous post has been edited with an updated, much better version of the sample project because I felt I could do better.

Whatisaspacebar
09-10-2004, 07:04 PM
Hey, I continued to go deeper into that sample program I made with hopes of finding out what I'm about to say, but I got nada...

Is there any possible way (other than TransparentBlt) to blit that 3rd picture's transparency, without modifying the original loaded picture's pixel colors to white? There's got to be someway to go about this, but I can't figure it out. Any suggestions?

pikzel_R
09-11-2004, 03:49 PM
Hey, I continued to go deeper into that sample program I made with hopes of finding out what I'm about to say, but I got nada..Any suggestions?
I took a look at your revised attachment.

The code in modBltmask.bas was interesting, but was pretty much black or white in terms of color keying. Putting the checking for bitblting inside the form's Paint event was an interesting...haven't seen any code that did it that way before...adding dragging was a nice touch also. But it's kind of jumpy because there's no test to see if you are actually initiating a MouseDown directly on the bitblt-ed image to be dragged (before changing the image's position).

The fact that you've already chosen to update your sample once, as well as the content of your last post, leads me to believe you want to keep developing your sample further and I hope you do so, but what is needed is to develop your code to have a more robust structural framework.

There are a number of ways to do this..

One way is to use a class to initialize you memoryDC (and do the cleanup). The other is to develop a full fledged rendering loop tied in with an API timer. Even if you are not planning to do animation it will help your program to operate better as well as make it easier to update and make changes.

To accomplish both these things you might want to take a look at Noi_Max's attachments in this thread:
http://www.xtremevbtalk.com/t184577.html

He also shows how to use a different color (magenta) as the masking color key and his classes allow for bitblting more than just two layers.

For creating a "virtual" drag (by hit testing the bitblt mask to see if the MouseDown occurs within the bitblt-ed image), you can take a look at the "2cards" attachment I did on this post:
http://www.xtremevbtalk.com/showpost.php?p=828041

If it seems involved to do all these things, it is (just a little), but take your time, work through the implementaion, and I'm sure you'll come up with a better program. Good Luck :)

Whatisaspacebar
09-17-2004, 07:33 PM
Sorry for the late reply, but I had to get my router fixed. Couldn't come back online till then, unfortunately. Until I finally did, however, I've been working madly on this thing, and have turned it into a full-blown project. I have attached version 1.02 to this post. It's hella cool now IMHO... BTW, those links aren't too bad Pikzel, thanks. Wish I had them sooner =/ lol.

Special thanks to Pikzel_R and OnError are applied within. Please, both of you tell me what you think as soon as you can. Thanks!

pikzel_R
09-19-2004, 02:59 AM
BTW, those links aren't too bad Pikzel, thanks. Wish I had them sooner =/ lol.

Special thanks to Pikzel_R and OnError are applied within. Please, both of you tell me what you think as soon as you can. Thanks!
Sorry about the late-ness of the links - but looks like you didn't really need them.

Magic Toast and Underwear Gnomes :D - some nice code.

How long will we have to wait for the "resize a bitmap to fit the array" code promised in the SetColors comments? ...and more ways to use "Effect"?

But you already know what you have to do to make it more efficient - get rid of GetPixel/SetPixel and use VarPtrArray/CopyMemory:
http://www.rookscape.com/vbgaming/tutAY.php

Adding another memoryDC and using double buffering will get rid of the little bit of flicker while dragging..

Masking hundreds or colors at once is still quite impressive, but I was wondering (just giving the code a quick once over) about the CKey colorkey array and the use of:

Dim ck

Is that Dim ck as Variant?

passel
09-19-2004, 07:07 AM
..., but I was wondering (just giving the code a quick once
over) about the CKey colorkey array and the use of:

Dim ck

Is that Dim ck as Variant?

I assume you know that is a Variant (since the default type, if not declared, in
VB is Variant), and are just "hinting" ;) that for clarity it should be explicitly
declared so that one does not have to search for Deftype statements to see
if a Default Type has been defined that includes the letter "c".
i.e. DefInt A-E, I, L
or ...
DefBool letterrange[, letterrange] . . .
DefByte letterrange[, letterrange] . . .
DefInt letterrange[, letterrange] . . .
DefLng letterrange[, letterrange] . . .
DefCur letterrange[, letterrange] . . .
DefSng letterrange[, letterrange] . . .
DefDbl letterrange[, letterrange] . . .
DefDec letterrange[, letterrange] . . .
DefDate letterrange[, letterrange] . . .
DefStr letterrange[, letterrange] . . .
DefObj letterrange[, letterrange] . . .
DefVar letterrange[, letterrange] . . .

pikzel_R
09-19-2004, 01:07 PM
Thanks Passel. Yes, that's pretty much what I was hinting at...

I was think about the interface for the colorkey select dialog. You have it where if you select one color (as a hex value in the list) it will show a preview of that color, but if you select a range of colors, you really don't get an idea of the colors involved or how many pixels are effected.

Photoshop has a color range select dialog, but IMO it's pretty much a pain to work with, because it relies on a "Fuzziness" setting to determine the extent of the range of colors selected "around" the central color (that is picked by clicking on some pixel color with the eyedropper cursor).

At first I thought, instead of a list of hex values maybe you could have a picturebox where you filled rectangles (generated by Line method, BF paramter) for the range of color hex values selected...with, say, "5" pixels for the height/width of the colored rectangles and 2-3 pixels of white space in between. Then you could click on each color and it would be framed (again by using Line method with an unfilled rectangle, 6 pixels height/width) to show selection of that color. But then what if they wanted to do a rubberband select. That would get kind of involved perhaps...

Then I thought a little more...maybe you could try using sliders to select pixels with Red, Green, or Blue color components above a certain threshold value (see gif below).

Yes, doing the copying (or drawing) or all those pixels would be CPU intensive, but you are already cycling through all the pixels and this way would actually give the user a sense of which pixels would potentially be masked out. I don't know it's it's practical considering the speed issues involved, but I think unless you are designing the program for just programmers, then selecting colors ranges by hex value can be kind of awkward...

Just wanted to throw out some ideas. I really don't know in what context this program is being developed (what you intend..)

Whatisaspacebar
09-20-2004, 05:32 PM
Those are some truely creative ideas... Yes, I do intend on 'upping' the overall performance of the module using copymemory etc., but I figured I'd get something out there first - which is what this is.

This demo was made using Win98 and VB6, which unfortunately is what my crappy comp is stuck with at the moment. I am currently turning this module into a class module that works very much like a collection in the sense that all you need to do is use some "add" and "remove" functions, associated with a key (variant), in order to manipulate images. The "draw" function will also use the same ease of use with these keys, as specified by the programmer.

Two new functions added: CopyBitmap & CopyImage. CopyBitmap copies the entire contents (image included) of an SD_BITMAP UDT, whereas the CopyImage function only copies the contents of an image into an already premade SD_BITMAP variable.

More to come, so stay tuned! =)

P.S.: No, really. Them gnomes are some killer sum beetches.

Whatisaspacebar
09-22-2004, 06:21 PM
So far, This seems to work pretty good:
Option Explicit
Public Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Public Type SD_BITMAP_INFO
Type As Long
Width As Long
Height As Long
WidthBytes As Long
Planes As Integer
BitsPixel As Integer
Bits As Long
End Type
Public Type SD_HANDLE
hWnd As Long
hDC As Long
End Type
Public Type SD_BITMAP
Filename As String
Handle As SD_HANDLE
Info As SD_BITMAP_INFO
Masked As Boolean
Modified As Boolean
End Type
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Public Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal Width As Long, ByVal Height As Long, ByVal opmode As Long) As Long
Public Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
Public Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Public Declare Function GetObjectA Lib "gdi32" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Public Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Public Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long

Private Function FileExists(Filename As String) As Boolean

On Error GoTo ErrOut

Call FileLen(Filename)
FileExists = True
Exit Function

ErrOut:
End Function
Public Function LoadBitmap(Filename As String) As SD_BITMAP
Dim sd_bmpBitmap As SD_BITMAP
Dim sd_bmp As SD_BITMAP_INFO

If Not FileExists(Filename) Then Exit Function
With sd_bmpBitmap
.Filename = Filename
.Handle.hWnd = LoadImage(0, Filename, 0, 0, 0, &H10)
.Handle.hDC = CreateCompatibleDC(0)
Call SelectObject(.Handle.hDC, .Handle.hWnd)
Call GetObjectA(.Handle.hWnd, Len(sd_bmp), sd_bmp)
.Info = sd_bmp
.Masked = False
.Modified = False
End With

LoadBitmap = sd_bmpBitmap
End Function
Public Function CreateMask(SrcImage As SD_BITMAP, Optional ColorKey As Long) As SD_BITMAP
Dim C_MASK_BLACK As RGBQUAD
Dim C_MASK_WHITE As RGBQUAD
Dim sd_bmpMask As SD_BITMAP
Dim BitsMain() As Byte
Dim BitsMask() As Byte
Dim bLen As Byte
Dim lSize As Long
Dim Index As Long
Dim px As Long
Dim py As Long
Dim r As Long
Dim g As Long
Dim b As Long

If Not FileExists(SrcImage.Filename) Or SrcImage.Masked Or SrcImage.Modified Then Exit Function
sd_bmpMask = LoadBitmap(SrcImage.Filename)

With C_MASK_BLACK
.rgbBlue = 0
.rgbGreen = 0
.rgbRed = 0
.rgbReserved = 0
End With
With C_MASK_WHITE
.rgbBlue = 255
.rgbGreen = 255
.rgbRed = 255
.rgbReserved = 0
End With

With sd_bmpMask
lSize = (.Info.WidthBytes * .Info.Height)
ReDim BitsMask(0 To lSize)
ReDim BitsMain(0 To lSize)
Call GetBitmapBits(.Handle.hWnd, lSize, BitsMask(0))
Call CopyMemory(BitsMain(0), BitsMask(0), lSize)
bLen = (.Info.BitsPixel \ 8)
If bLen = 0 Then Exit Function

For Index = 0 To (lSize - bLen) Step bLen
If RGB(BitsMask(Index + 2), BitsMask(Index + 1), BitsMask(Index)) = ColorKey Then
Call CopyMemory(BitsMain(Index), C_MASK_BLACK, bLen)
Call CopyMemory(BitsMask(Index), C_MASK_WHITE, bLen)
Else
Call CopyMemory(BitsMask(Index), C_MASK_BLACK, bLen)
End If
Next Index

Call SetBitmapBits(SrcImage.Handle.hWnd, lSize, BitsMain(0))
Call SetBitmapBits(.Handle.hWnd, lSize, BitsMask(0))
SrcImage.Modified = True
.Masked = True
End With

CreateMask = sd_bmpMask
End Function
Public Function DrawNormal(SrcImage As SD_BITMAP, hdcDest As Long, Optional X As Long, Optional Y As Long) As Boolean
On Error GoTo ErrOut
With SrcImage
Call BitBlt(hdcDest, X, Y, .Info.Width, .Info.Height, .Handle.hDC, 0, 0, vbSrcCopy)
End With
DrawNormal = True
Exit Function

ErrOut:
DrawNormal = False
End Function
Public Function DrawTransparent(MainImage As SD_BITMAP, MaskImage As SD_BITMAP, hdcDest As Long, Optional X As Long, Optional Y As Long) As Boolean
Dim Flag As Integer

On Error GoTo ErrOut
With MaskImage
If .Masked And Not .Modified Then
Call BitBlt(hdcDest, X, Y, .Info.Width, .Info.Height, .Handle.hDC, 0, 0, vbSrcAnd)
Else
Flag = Flag + 1
End If
End With
With MainImage
If Not .Masked Then
Call BitBlt(hdcDest, X, Y, .Info.Width, .Info.Height, .Handle.hDC, 0, 0, vbSrcPaint)
Else
Flag = Flag + 1
End If
End With
If Flag < 2 Then DrawTransparent = True
Exit Function

ErrOut:
DrawTransparent = False

End Function
However, when I tried to implement the pointer method, It didn't work so great:
Option Explicit
Public Type SAFEARRAYBOUND
cElements As Long
lLbound As Long
End Type
Public Type SAFEARRAY2D
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
Bounds(0 To 1) As SAFEARRAYBOUND
End Type
Public Type BITMAP_STRUCT
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Public Type SD_HANDLE
hWnd As Long
hDC As Long
End Type
Public Type SD_BITMAP
Filename As String
handle As SD_HANDLE
Info As BITMAP_STRUCT
Masked As Boolean
Modified As Boolean
End Type
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Public Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal Width As Long, ByVal Height As Long, ByVal opmode As Long) As Long
Public Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
Public Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Public Declare Function GetObjectA Lib "gdi32" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Public Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long
Public Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Public Function LoadBitmap(Filename As String) As SD_BITMAP
Dim sd_bmpBitmap As SD_BITMAP
Dim sd_bmp As BITMAP_STRUCT

If Not FileExists(Filename) Then Exit Function
With sd_bmpBitmap
.Filename = Filename
.handle.hWnd = LoadImage(0, Filename, 0, 0, 0, &H10)
.handle.hDC = CreateCompatibleDC(0)
Call SelectObject(.handle.hDC, .handle.hWnd)
Call GetObjectA(.handle.hWnd, Len(sd_bmp), sd_bmp)
.Info = sd_bmp
.Masked = False
.Modified = False
End With

LoadBitmap = sd_bmpBitmap
End Function
Public Function CreateMask(SrcImage As SD_BITMAP, Optional ColorKey As Long) As SD_BITMAP
Dim sd_bmpMask As SD_BITMAP
Dim pic() As Byte
Dim sa As SAFEARRAY2D
Dim px As Long
Dim py As Long
Dim pr As Long
Dim pg As Long
Dim pb As Long

If Not FileExists(SrcImage.Filename) Then Exit Function
sd_bmpMask = LoadBitmap(SrcImage.Filename)

With sa
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = sd_bmpMask.Info.bmHeight
.Bounds(1).lLbound = 0
.Bounds(1).cElements = sd_bmpMask.Info.bmWidthBytes
.pvData = sd_bmpMask.Info.bmBits
End With
Call CopyMemory(ByVal VarPtrArray(pic), VarPtr(sa), 4)
For px = 0 To UBound(pic, 1) - 3 Step 3
For py = 0 To UBound(pic, 2)
pr = (px + 2)
pg = (px + 1)
pb = px
If RGB(pic(px + 2, py), pic(px + 1, py), pic(px, py)) = ColorKey Then
pic(pr, py) = 255
pic(pg, py) = 255
pic(pb, py) = 255
Else
pic(pr, py) = 0
pic(pg, py) = 0
pic(pb, py) = 0
End If
Next py
Next px
Call CopyMemory(ByVal VarPtrArray(pic), 0&, 4)
CreateMask = sd_bmpMask
End Function
The reason the pointer method fails is cause the BITMAP_STRUCT area of my UDT SD_BITMAP doesn't get bmBits, which acts as a pointer to an image's bits. The only way I know of recieving this pointer is through the means of a PictureBox or an StdPicture object. Any ideas?

anon
09-22-2004, 07:45 PM
The reason the pointer method fails is cause the BITMAP_STRUCT area of my UDT SD_BITMAP doesn't get bmBits, which acts as a pointer to an image's bits. The only way I know of recieving this pointer is through the means of a PictureBox or an StdPicture object. Any ideas?

Have you tried using the Get Object API?

There's some code by Termor in the first post of this thread:
http://www.xtremevbtalk.com/t46295.html
Here's an excerpt..

Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" _
(ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, _
ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long

' This loads in a bitmap to a device context from a file.
Public Function LoadPicture(ByVal FileName As String, ByRef Width As Long, ByRef Height As Long) As Long
Dim lngBitmap As Long
Dim lngDC As Long
Dim udtBitmapData As BITMAP

' Create a Device Context.
lngDC = CreateCompatibleDC(0)
If lngDC = 0 Then Exit Function

' Load the image.
lngBitmap = LoadImage(0, FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
If lngBitmap = 0 Then
' Failure in loading bitmap.
Call DeleteDC(lngDC)
Exit Function
End If

' Get Width & Height of the bitmap.
Call GetObject(lngBitmap, Len(udtBitmapData), udtBitmapData) ' --bmBits info retreived!
Width = udtBitmapData.bmWidth
Height = udtBitmapData.bmHeight

' Put the Bitmap into the device context.
Call SelectObject(lngDC, lngBitmap)
Call DeleteObject(lngBitmap)

' Return the device context.
LoadPicture = lngDC
End Function

Be careful of using the whole code snippet, he's not doing proper clean-up and it has a memory leak (as is noted later in the thread)

Whatisaspacebar
09-27-2004, 05:23 PM
Once again, sorry for the late replies... I'm a very busy man, unfortunately.

Anon, I appreciate the help, however I don't think you took a look at my code... GetObjectA (which is what I've been using for this entire project) isn't returning a pointer to bmBits! If you download the sample demo you will see how everything works - and it all works fine, with the exception of bmBits not getting filled. What my next goal here is, is to use the pointer method that Pikzel_R suggested, in order to speed this sample demo up a notch or two. The pointer method, however, seems to only work when the bmBits variable holds the appropriate pointer to the image's bits. Anyways, just in case I'm overlooking something in that code snippet you posted, I will still take a look, regardless of the fact that it appears to be the same method I've been using all along.

From what I can figure out, the bmBits variable seems to only recieve a non-zero value when GetObjectA is used with a PictureBox or an StdPicture object.

Whatisaspacebar
09-28-2004, 06:45 PM
Yup, thought so. Even in your code, anon, bmBits doesn't seem to recieve anything at all. Everything else works fine, however, just the same way that my code works. So now I know that I haven't overlooked anything that you've posted. I still thank you and hope that you can still help me out here, cause I'm still at sqaure one with this puzzle.

Can anyone else *please* jump in here with your thoughts? I would really love to finish this for the visualbasicforum community....

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum