Results 1 to 12 of 12

Thread: [RESOLVED] Is it possible to use IpictureDisp with BitBlt?

  1. #1

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    Resolved [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.

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    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.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    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
    Code:
    print img(0).width
    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

  4. #4
    Fanatic Member DrUnicode's Avatar
    Join Date
    Mar 2008
    Location
    Natal, Brazil
    Posts
    631

    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

  5. #5

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    Re: Is it possible to use IpictureDisp with BitBlt?

    Quote 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)?

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    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.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    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)

  8. #8

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    Re: Is it possible to use IpictureDisp with BitBlt?

    Quote 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.

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    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
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    Re: Is it possible to use IpictureDisp with BitBlt?

    Quote 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

  11. #11
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    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
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  12. #12

    Thread Starter
    Lively Member VBNubcake's Avatar
    Join Date
    Feb 2008
    Location
    Caledon, Ontario, Canada
    Posts
    80

    Re: [RESOLVED] Is it possible to use IpictureDisp with BitBlt?

    Quote 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
  •  



Click Here to Expand Forum to Full Width