dcsimg
Results 1 to 12 of 12

Thread: Capturing an image of two controls

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    550

    Capturing an image of two controls

    The below code will capture an image of a button control and save it on the disk:

    Code:
    Private Sub cmdCaptureButton_Click()
     Dim ControlDC As Long
     Dim r As Long
    
     Picture1.Cls
     Picture1.AutoRedraw = True
    
     Picture1.Width = Command1.Width
     Picture1.Height = Command1.Height
     
     ControlDC = GetDC(Command1.hwnd)        ' get DC for the button
     
     r = BitBlt(Picture1.hdc, _
            0, 0, _
            Command1.Width, Command1.Height, _
            ControlDC, _
            0, 0, _
            SRCCOPY)
            
     Picture1.Refresh
            
     ReleaseDC Command1.hwnd, ControlDC
     
     Clipboard.Clear
     Clipboard.SetData Picture1.Image, vbCFBitmap
     SavePicture Picture1.Image, App.Path & "\BUTTON.BMP"
    End Sub
    Now I have two controls (not necessary two buttons however) sitting side-by-side. How can I capture an image of both controls into one image without having other nearby controls being included.

  2. #2
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    824

    Re: Capturing an image of two controls

    almost the same as u have
    but u do it twice, u copy command2 and using bitblt and the 0 = "x" is command1.width.
    picture1 need to be both command1+command2 width.

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    550

    Re: Capturing an image of two controls

    Doesn't work because it picks up pieces of other controls nearby. It works with the button because it has a rectangular shape but the controls I'm using do not; they have irregular shapes and anything that is not the image is white (transparent color) so I guess I need to find another way

  4. #4
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    5,504

    Re: Capturing an image of two controls

    If you have an irregular shape, then you need a mask that matches that shape to keep the part of the image you want to capture.
    If you have a white version of the irregular shape with a black background as the mask, then bitblt or paint that mask to your captured image with a SrcAnd raster Op, it will clear all the area that is not part of the shape.

    If you wanted to draw that shape on another image, then you would SrcAnd the inverse of the mask to the destination first to "cut a hole" in the image, and then blit the image to the destantion with a SrcPaint (Or) operation to fill in the hole.

    Or you could just create an image appropriately with a color representing the transparent background, which it kind of sounds like what you might be doing, and use transparent blt to essentially to the above with one call, rather than two calls.

  5. #5
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    824

    Re: Capturing an image of two controls

    another alternative is to create a 32-bit PARGB and copy the control to it,
    using CreateDIBSection you can loop through the image and change the alpha of unwanted colors.
    ans save as *.png format to preserve alpha.

  6. #6
    Hyperactive Member
    Join Date
    Feb 2019
    Posts
    440

    Re: Capturing an image of two controls

    For irregular shapes, you could use TransparentBlt, which copies everything except a specified color. If the background is white, then also anything inside the irregular shape that is white would be treated as transparent as well.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    550

    Re: Capturing an image of two controls

    I'm not too sure TransparentBlt will work as there will always be more than one unwanted colors to deal with. I have included three pictures to show what I am up against.

    The top image shows the pieces before the player moves two pieces together

    The bottom image shows the pieces after the player inter-locked two pieces

    The image on the bottom right is what I need to capture

    Note that the captured image does not show any of the other surrounding pieces. Once I have this image I then create a new user control and load the captured image into the control and position it at the same location of the two pieces that are inter-locked. Then I unload the two inter-locked pieces and now a new control takes their place on the board. This is done so that the player will move both pieces when he selects one or the other to move.

    The capturing must be done off screen so that the process can't be seen by the player
    Attached Images Attached Images    

  8. #8
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,449

    Re: Capturing an image of two controls

    How are your pieces done with transparency? Using mask bitmaps? If so, couldn't you create a new bitmap with the two masks rendered side-by-side then supply that bitmap as the mask for the new usercontrol? Just thinking out loud

    P.S. Over a decade ago, I thought about creating something like you are doing but gave up before I even started -- my graphics skills weren't as developed as they are now and my goals were too big. Anyway, one problem with gluing the pieces together -- what if the user wants to unglue them? Let's say that multiple pieces have identical shapes and user glued the wrong one into place? It will need to be unglued and replaced with the correct piece.
    Last edited by LaVolpe; Jun 22nd, 2019 at 06:48 PM.
    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}

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    550

    Re: Capturing an image of two controls

    My code, hopefully, will prevent the player from getting two pieces glued together if they are not the correct pieces. I have some some rough and vague ideas about this but haven't got to that point yet. I'll worry about that later

    The biggest concern I have is how is the program going to know when two pieces have been locked together so it can auto call the gluing sub. Right now, for testing, I have to manually call the sub every time I lock two pieces together by entering the indices of the two pieces in a textbox and click on a button to call the sub (see below)

    You ask how are my pieces done with transparency? Using mask bitmaps?

    All my pieces are bitmaps (not transparent gifs or any other type of image). All are puzzle piece pictures on a white background and I set the user control mask property to vbWhite

    Code:
       '
       '
    Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
     If Ambient.UserMode Then
       BackStyle = 0                      ' = Transparent.
       MaskColor = vbWhite 
       Set MaskPicture = Picture
     End If
       
     With PropBag
       Set Picture1 = .ReadProperty("Picture1", Nothing)
     End With
    End Sub
    
    Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
     With PropBag
       .WriteProperty "MaskColor", MaskColor, vbButtonFace
       .WriteProperty "Picture1", Picture1, Nothing
      End With
    End Sub
    
    Private Sub UserControl_Initialize()
     UserControl.BackColor = vbWhite
     UserControl.BackStyle = 0
     
     MyPicture1.Move 0, 0, UserControl.ScaleWidth, UserControl.ScaleHeight
    End Sub
        '
        '
    You also stated couldn't you create a new bitmap with the two masks rendered side-by-side then supply that bitmap as the mask for the new usercontrol? Just thinking out loud

    I think I am doing something like that now.....

    Code:
    Private Sub GluePieces(P1 As Integer, P2 As Integer)
     '
     ' P1 and P2 are the indices of the two pieces being "glued" together
     '
     picNewPiecesCombination(1).Width = ucPuzzlePiece(P1).Width + ucPuzzlePiece(P2).Width
     picNewPiecesCombination(1).Height = ucPuzzlePiece(P1).Height + ucPuzzlePiece(P2).Height
     picNewPiecesCombination(1).Picture = ucPuzzlePiece(P1).Picture1
     
     picNewPiecesCombination(2).Width = ucPuzzlePiece(P2).Width 
     picNewPiecesCombination(2).Height = ucPuzzlePiece(P2).Height 
     picNewPiecesCombination(2).Picture = ucPuzzlePiece(P2).Picture1
    
     For X = 0 To picNewPiecesCombination(2).ScaleWidth
       For Y = 0 To picNewPiecesCombination(2).ScaleHeight
         k = picNewPiecesCombination(2).Point(X, Y)
         If k <> vbWhite Then
           picNewPiecesCombination(1).PSet (X + ucPuzzlePiece(P2).Left - ucPuzzlePiece(P1).Left, Y), k
         End If
       Next Y
     Next X
     
     picNewPiecesCombination(1).Picture = picNewPiecesCombination(1).Image
     
     CropPicture picNewPiecesCombination(1) 'Crop this image
     
     picNewPiecesCombination(1).AutoRedraw = True
     
     On Error GoTo ExitSub
    
     Dim p1Left As Integer
     Dim p1Top As Integer
    
     p1Left = ucPuzzlePiece(P1).Left
     p1Top = ucPuzzlePiece(P1).Top
    
     Unload ucPuzzlePiece(P1)
     
     Load ucPuzzlePiece(P1)
     
     ucPuzzlePiece(P1).Visible = True
      
     ucPuzzlePiece(P1).Width = picNewPiecesCombination(1).Width
     ucPuzzlePiece(P1).Height = picNewPiecesCombination(1).Height
      
     ucPuzzlePiece(P1).LoadPicture picNewPiecesCombination(1).Picture
    
     ucPuzzlePiece(P1).Move p1Left, p1Top
     
     Unload ucPuzzlePiece(P2)
    ExitSub:
      '
      '
    End Sub
    The above appears to be working OK so far but only for some combinations and others dont align up correctly. Somehow in my mind I think I am going to run into a lot of problems down the line and that is why I thought that a snapshot of the two pieces already locked together would be better as it would for sure be a correct image of what I need instead of me doing what this code does.
    Last edited by Code Dummy; Jun 22nd, 2019 at 07:42 PM.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    550

    Re: Capturing an image of two controls

    After giving some thought to the code I have to glue the two images I probably can figure out why some don't come out right and I think it's the top position hasn't been recalculated like I did for the left position.

  11. #11
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    5,504

    Re: Capturing an image of two controls

    My wife has been in the hospital, and while sitting in the hospital room today thinking about something to do to pass the time, I decided to start working on a version of a jigsaw program myself, so I can have some examples to demonstrate approaches I would take and have mentioned in past posts.
    Of course, currently, I work with VB.Net primarily, so some aspects would be easier for me these days in that language, but I'm doing this with VB6 since that is the language of this topic.

    I haven't gotten too far yet. Rather than work with more traditional looking pieces like you have, I just started with creating a grid (our original 5x5) with a checkerboard background, white and black. Then added white circles overlapping the four edges a bit to provide the interlocking bits (nodes I call them). I just place the circles along the edges some random distance far enough away from the corner to not overlap the node of another piece's node. Once created I loop through to pull the masks for each piece into an array of bitmaps (I'm using non-visible pictureboxes for convenience).

    The point for posting this, is that while the pieces will be different sizes visually, (in my case, since the pieces are generated in a simple manner, the pieces are actually only two different sizes, those with nodes are one size, and those without are another, smaller size), the size of all the bitmaps will be the same size. The image of the piece will be centered in the bitmap.

    That means the center of the bitmap will align with the center of the grid square, so I'll be using that center point as the reference point for the piece. Since the centerpoints will all be the same distance apart, it will be easy to tell when they are aligned, or close enough to be locked in place, and to move any number of locked pieces together.

    The way I plan on locking the pieces is a method I've used in the past to move multiple objects together. I have a structure that contains a reference to a piece and two links. Thus any connected pieces can be linked together as a duel linked list, and when you move anyone of the pieces, the links are checked, and any linked pieces are moved as well.

    It seems since you should know where all the user controls should be placed in order to have the completed image, you should be able to calculated a reference point (probably an X,Y offset within the control) that is the center point of the image, and those points would be the same distance apart for all your pieces from any adjacent piece.

    In your case, the reference point may not be in the center of the pieces, but you should be able to have a grid of points (one point in each piece) that can be equal distance apart and serve as an easy way to test for proper positioning of pieces.
    I don't know if you want to consider that approach or continue your course, but if I continue working my version and get to a point where I can create the pieces, move, rotate and interlock, I'll post it for the curious.

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Apr 2017
    Posts
    550

    Re: Capturing an image of two controls

    Sounds great! Can't hardly wait!

    Sorry to hear about your wife. Hope she is doing fine and nothing serious

    I have just completed the "gluing" routine of the pieces - it works 100%. I connected every piece and they all stuck to each other as I dragged them. Of course I had to manually click on button to "glue" them which bring me to my next step. The next step is to figure out when two pieces have been interlocked by the player and it is correct so my program will auto call the piece "gluing" routine.

    I tried the link list approach but on my computer it turns out terrible. I don't know how well it will work on your PC. It's a good idea but the problem is when you start to have too many pieces connected together and you drag one piece and it will drag the other pieces in the link list it starts to smear a lot and as new pieces are added the smearing gets worse and it also makes the dragging slow. I didn't care for that approach so I went back to the one I'm using which you can drag all the pieces and it wont cause any problems and there is no additional overhead to be concerned with.
    Last edited by Code Dummy; Jun 24th, 2019 at 09:20 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width