|
-
Apr 23rd, 2008, 07:25 PM
#1
Thread Starter
Lively Member
[RESOLVED] Is it possible to use IpictureDisp with BitBlt?
Is it possible to use an IpictureDisp variable with BitBlt?
This is in module:
Code:
'Enable BitBlt
Public Declare Function BitBlt Lib "gdi32.dll" _
(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
This is in form:
Code:
Dim pic As IPictureDisp
Private Sub Command1_Click()
Form1.AutoRedraw = True
Picture1.AutoRedraw = True
Set pic = LoadPicture("D:\Alejandro\VB Programs\RPG\Sprites and Bitmaps\Enemies\dim master.gif")
picture1.cls
BitBlt Picture1.hDC, 0, 0, pic.Width, pic.Height, pic.Handle, 0, 0, vbSrcCopy
End Sub
I'm not too sure if pic.Handle is supposed to be used here...
But essentially, I just want to use bitblt (or any similar function for that matter) without having to keep track of the pixel dimensions of the source image. Cause im trying to create animations (multiple pictures) and for each picture I have to keep track of the exact dimension of each picture so it blts properly, for example this is what i want to avoid:
Code:
Const DimMasterWidth = 119
Const DimMasterHeight = 153
picture1.cls
BitBlt Picture1.hDC, 0, 0, DimMasterWidth, DimMasterHeight, picSource.hDC, 0, 0, vbSrcCopy
I wanna be able to load the pictures into the program at the beginning of runtime and i want vb to automatically keep track of the dimensions through Pic.Width and Pic.Height or something along those lines. Essentially, i dont wanna have to type in:
Code:
Const DimMasterWidth = 119
Const DimMasterHeight = 153
because i have ALOT of pictures (hundreds), and its alot of tedious work (and i think unnecessary).
Any suggestions? I'm open to new functions as well, anything at all. I've tried Pic.Render instead of BitBlt except i cant seem to keep the scale size the same (reply if you wanna see my code for that method).
Help plz
Last edited by VBNubcake; Apr 24th, 2008 at 09:01 AM.
-
Apr 24th, 2008, 05:19 PM
#2
Re: Is it possible to use IpictureDisp with BitBlt?
Not sure if I understand your question -- the answer to your question could be relatively simple however.
You have images of varying dimensions, correct? What is suppose to happen when the image you are painting is larger or smaller than the master dimensions? Is the image to be stretched, scaled or clipped? BitBlt can only do the clipped portion whereas StretchBlt can do all (assuming you provide the correct scaling dimensions).
Anyway, .Render will work & I can show you how after I understand what you really need.
-
Apr 24th, 2008, 07:07 PM
#3
Thread Starter
Lively Member
Re: Is it possible to use IpictureDisp with BitBlt?
the answer to your question is clipped
i know .render has parameters to stretch images but i dont want to stretch the images, i just want the images to remain their normal size
basically i have an image of a "game character" and when he "walks" i want to cycle some images of him to make it look as though he's walking (i.e. rightfoot forward, leftfoot forward...etc). Also, i also want my character to move while he is walking.
I'm familiar with how to do that using bitblt but the way im using bitblt, i find is a little tedious. In a tutorial i found, it suggested that i should use bitblt by copying a single source picture (called picSourceColors) that has ALL images that i want to draw. It also suggested i created an identical picture of their masks (called picSourceMasks). They suggested I opened photoshop, and pasted all my images side-by-side (connected precisely by a single pixel). Then, when I want to use bitblt, it suggests that I just copy a certain portion of picSourceMasks and picSourceColors.
For example, if the first image is 45x45 (pixels) and the second is (50x50), picSourceColors and picSourceMasks would be 90x50 pixels. If i wanted to draw the second image to a certain location (i.e. picDestination), i would have to do something like this:
Code:
'Blt (Mask)
BitBlt picDestination.hDC, 0, 0, 50, 50, picSourceMasks.hDC, 50, 0, vbSrcAnd
'Blt (Color)
BitBlt picDestination.hDC, 0, 0, 50, 50, picSourceColors.hDC, 50, 0, vbSrcPaint
What i have right now is basically a really really wide picSourceMasks and picSourceColors (over 10000 pixels). So what i was wondering is if there's a way to not have to keep entering in the dimensions of various images. In this case it was 50,50 starting 50 pixels from the left of picSourceMasks and picSourceColors.
Now lets say i wanted to bitblt the 30th image..it might be something like 239,268 starting 700 pixels from the left of picSourceMasks and picSourceColors. I would have to know exactly that image 30 was 239x268 pixels and i would also have to know that it starts 700 pixels from the left of picSourceMasks and picSourceColors.
When i realized there was a variable that actually stores images (IpictureDisp) i got a little excited because it has fields including .width and .height. So i was thinking maybe instead of using picSourceMasks and picSourceColors, i could just do this for all the picture i have for all the pictures I have:
Code:
Dim Img(30) as IPictureDisp
Set Img(0) = LoadPicture("Location")
Set Img(1) = LoadPicture("Location")
Set Img(2) = LoadPicture("Location")
and so on until all images are stored into the array (I didnt actually type "Location" in vb, its just generic for this post)
I tried doing this but then bitblt didnt work and i concluded that I had two possible problems:
1) lets say the width of image stored in img(0) was 82 pixels and if i did something like i would get a value of 2064. So my guess is that img(0).width is not scaled by pixels...im not too sure if this is a problem for the bitblt function or not.
2) when i use bitblt, im not too sure what to replace picSourceColors.hDC and picSourceMasks.hDC with (which is why i highlighted pic.Handle in post #1...well in this case it would be img(0).Handle)
this is when i started considering to scrap the bitblt function and start using the newly discovered Img(0).Render. My only problem with that though is that .Render requires a scale to stretch/compress but i dont want to resize anything and i have no clue how to set the scale properly so it doesnt resize
if you didnt gouge out your eyes after reading this rather lengthy post, can you let me know if you understand my problem a little better? i really appreciate your help
-
Apr 24th, 2008, 08:06 PM
#4
Re: Is it possible to use IpictureDisp with BitBlt?
You can get the actual Picture Width/Height in Pixels using ScaleX:
BitBlt Picture1.hDC, 0, 0, _
ScaleX(picSource.Width, vbHimetric, vbPixels), _
ScaleX(picSource.Height, vbHimetric, vbPixels), _
picSource.hDC, 0, 0, vbSrcCopy
-
Apr 24th, 2008, 08:45 PM
#5
Thread Starter
Lively Member
Re: Is it possible to use IpictureDisp with BitBlt?
 Originally Posted by DrUnicode
You can get the actual Picture Width/Height in Pixels using ScaleX:
BitBlt Picture1.hDC, 0, 0, _
ScaleX(picSource.Width, vbHimetric, vbPixels), _
ScaleX(picSource.Height, vbHimetric, vbPixels), _
picSource.hDC, 0, 0, vbSrcCopy
wicked, works very nicely thanks alot!!!!!
but to take it one step further (if you dont mind), is it possible to do something like this:
Code:
'Enable BitBlt
Private Declare Function BitBlt Lib "gdi32.dll" _
(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
Dim Img As IPictureDisp
Private Sub Command1_Click()
Picture1.Cls
BitBlt Picture1.hDC, 0, 0, ScaleX(Img.Width, vbHimetric, vbPixels), ScaleY(Img.Height, vbHimetric, vbPixels), Img.Handle, 0, 0, vbSrcCopy
End Sub
Private Sub Form_Load()
Set Img = LoadPicture("Location")
Picture2.Picture = LoadPicture("Location")
Picture1.AutoRedraw = True
Picture1.AutoSize = True
Picture2.AutoSize = True
End Sub
The above code does not work, but essentially what im asking is, do you NEED to copy from a second picturebox (in your code its picSource.hDC), or can you use a variable that stores an image in it instead (in this case the variable is called Img)?
-
Apr 24th, 2008, 09:02 PM
#6
Re: Is it possible to use IpictureDisp with BitBlt?
Is it possible? Yes and no. The parameter required by BitBlt is a DC, not a image handle. Therefore, you would need to create a memory dc, select image into it, then BitBlt from that DC, then unselect image.
Using Render, it can be done relatively easily and .Render draws transparent gifs, icons, cursors, jpgs, and bitmaps without any special considerations:
Code:
Private Sub Command1_Click()
Dim tPic As StdPicture
Set tPic = LoadPicture([image path/file name])
With tPic
.Render Picture1.hDC, 0&, 0&, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
End Sub
P.S. IPictureDisp and stdPicture can be used pretty much interchangeably.
-
Apr 24th, 2008, 09:09 PM
#7
Thread Starter
Lively Member
Re: Is it possible to use IpictureDisp with BitBlt?
thx LaVolpe, while i was typing this post, i got a reply and you answered some of my questions, anyways, here's what my code looks like, im going to try your code right after this post
Code:
'Enable BitBlt
Private Declare Function BitBlt Lib "gdi32.dll" _
(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
Dim Img As IPictureDisp
Private Sub Command1_Click()
Picture2.Picture = Img
Picture2.Refresh
Print ScaleX(Img.Width, vbHimetric, vbPixels)
Print ScaleY(Img.Height, vbHimetric, vbPixels)
Print Picture2.Width
Print Picture2.Height
Picture1.Cls
Img.Render Picture1.hDC, 0, 0, ScaleX(Img.Width, vbHimetric, vbPixels), ScaleY(Img.Height, vbHimetric, vbPixels), 0, Img.Height, Img.Width, -Img.Height, vbSrcCopy
End Sub
Private Sub Form_Load()
Set Img = LoadPicture("Location")
Picture1.AutoRedraw = True
Picture1.AutoSize = True
Picture2.AutoSize = True
End Sub
im not 100% sure how to use image rendering though lol, i dont know why i used -img.Height
could you possibly give me a brief explanation of the bolded parameters .render uses? (i.e. hdc,x,y,cx,cy,xSrc,ySrc,cxSrc, cySrc, prcWBounds)
-
Apr 24th, 2008, 09:17 PM
#8
Thread Starter
Lively Member
Re: Is it possible to use IpictureDisp with BitBlt?
 Originally Posted by LaVolpe
Is it possible? Yes and no. The parameter required by BitBlt is a DC, not a image handle. Therefore, you would need to create a memory dc, select image into it, then BitBlt from that DC, then unselect image.
Using Render, it can be done relatively easily and .Render draws transparent gifs, icons, cursors, jpgs, and bitmaps without any special considerations:
Code:
Private Sub Command1_Click()
Dim tPic As StdPicture
Set tPic = LoadPicture([image path/file name])
With tPic
.Render Picture1.hDC, 0&, 0&, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
End Sub
P.S. IPictureDisp and stdPicture can be used pretty much interchangeably.
i tried your code, works great, but along with the explanation i requested in #7, could you also explain why you used "0&". ive seen lots of people use $ and & and i have no clue why.
i really really really appreciate the help both you guys already gave me, ty very much.
-
Apr 24th, 2008, 09:19 PM
#9
Re: Is it possible to use IpictureDisp with BitBlt?
Brief explanation? Sure.
Keep in mind that .Render uses 2 scalemodes: pixels for the destination & himetric for the source. The stdPicture/IPictureDisp measurements are in himetric; thus need to use ScaleX,ScaleY.
xSrc & ySrc. Where from source image to begin painting from.
cxSrc, cySrc. How much of the source to paint.
Basically the Render function parameters are nearly identical to StretchBlt.
Why use .Height & -.Height? The images in a stdPicture are upside down. If you were to use 0 & .Height instead, your image would be rendered upside down, so we need to invert those 2 dimensions.
P.S. &, $, #, etc are variable types
&=Long, %=Integer, $=string, #=double, !=Single
-
Apr 24th, 2008, 09:23 PM
#10
Thread Starter
Lively Member
Re: Is it possible to use IpictureDisp with BitBlt?
 Originally Posted by LaVolpe
Brief explanation? Sure.
Keep in mind that .Render uses 2 scalemodes: pixels for the destination & himetric for the source. The stdPicture/IPictureDisp measurements are in himetric; thus need to use ScaleX,ScaleY.
xSrc & ySrc. Where from source image to begin painting from.
cxSrc, cySrc. How much of the source to paint.
Bascially the Render function is nearly identical to StretchBlt.
Why use .Height & -.Height? The images in a stdPicture are upside down. If you were to use 0 & .Height instead, your image would be rendered upside down, so we need to invert those 2 dimensions.
P.S. &, $, #, etc are variable types
&=Long, %=Integer, $=string, #=double, !=Single
you rock
-
Apr 25th, 2008, 08:21 AM
#11
Re: [RESOLVED] Is it possible to use IpictureDisp with BitBlt?
You are welcome, but here is one thing you will want to remember -- annoyance with .Render
This produces a type mismatch error. Using variables in the destX,Y parameters.
Code:
Dim X As Long, Y As Long
With tPic
.Render Picture1.hDC, X, Y, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
But this does not, adding +0& to the X,Y coords resolves the problem. If rendering to an offscreen DC, you will also need to add +0& to the DC handle, but using a VB object DC does not generate the error.
Code:
Dim X As Long, Y As Long
With tPic
.Render Picture1.hDC, X + 0&, Y + 0&, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
-
Apr 25th, 2008, 11:16 AM
#12
Thread Starter
Lively Member
Re: [RESOLVED] Is it possible to use IpictureDisp with BitBlt?
 Originally Posted by LaVolpe
You are welcome, but here is one thing you will want to remember -- annoyance with .Render
This produces a type mismatch error. Using variables in the destX,Y parameters.
Code:
Dim X As Long, Y As Long
With tPic
.Render Picture1.hDC, X, Y, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
But this does not, adding +0& to the X,Y coords resolves the problem. If rendering to an offscreen DC, you will also need to add +0& to the DC handle, but using a VB object DC does not generate the error.
Code:
Dim X As Long, Y As Long
With tPic
.Render Picture1.hDC, X + 0&, Y + 0&, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
thx, i woulda ran into a problem later today if i didnt read that
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|