Results 1 to 10 of 10

Thread: Why are the two pictures not the same after Save and Load it agains?

  1. #1

    Thread Starter
    Addicted Member sergeos's Avatar
    Join Date
    Apr 2009
    Location
    Belarus
    Posts
    162

    Why are the two pictures not the same after Save and Load it agains?

    Hello,
    need to compare two pictures which are obtained using the function BitBlt:
    Code:
    hDC = GetWindowDC(GetDesktopWindow)
    BitBlt picTemp.hDC, 0, 0, Width, Height, hDC, left, top, vbSrcCopy
    picTemp.Picture = picTemp.Image
    then, i'm clone this picture to another:
    Code:
    BitBlt picDest.hDC, 0, 0, picTemp.Width, picTemp.Height, picTemp.hDC, 0, 0, vbSrcCopy
    picDest.Picture = picDest.Image
    and now, if i'm compare these pictures, they will be identical.
    (i'm using compare method from this place http://www.vbforums.com/showthread.p...=1#post2926566,
    also, attaching module with method to the post. Ex.: ImagesSame(Picture1, Picture2))

    But,
    when I'm saving picture from picDest:
    Code:
    SavePicture picDest.Picture, "C:\pic.bmp"
    and load again to PictureBox:
    Code:
    picDest.Picture = LoadPicture("C:\pic.bmp")
    picDest.Picture = picDest.Image
    These pictures are no longer identical!
    The question is how to make the loadable picture identical to the one that was obtained with the function BitBlt?
    ------------------------------------------------------------------------------------------------------------
    ModImageCompare.bas
    Ten Years After - 01 You Give Me Loving

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

    Re: Why are the two pictures not the same after Save and Load it agains?

    Are the two pictureboxes identically sized? Why are you calling LoadPicture, then setting the Picture property from the Image property? No point and could potentially change the .Picture property if the picbox inner dimensions are not the same size as the loaded picture.

    There are potentially several other problems with your code. I think you need to understand the difference between an object's Width and its ScaleWidth, its Height and ScaleHeight. A form's Width/Height is always measured in Twips. A control's Width/Height is measured in that control container's ScaleMode. ScaleWidth and ScaleHeight can be measured in scalemodes you dictate.

    That compare routine assumes that the picbox scalemode is pixels, not Twips or anything else.

    Edited: In my opinion trying to compare a screen capture of a desktop to some saved capture from a different date is pointless. Even when trying to compare captures just seconds apart can be different. For example, my desktop background is random and changes on its own while the pc is running. If a web browser was open, there could be animated images being displayed, the time displayed in the taskbar could change, and a wide range of other variables apply. Good luck with that.
    Last edited by LaVolpe; Oct 8th, 2017 at 11:18 AM.
    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
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Why are the two pictures not the same after Save and Load it agains?

    FYI: That comparison routine relies on more assumptions as I look at it deeper.

    Assumes: Picbox ScaleMode is pixels and AutoSize=True. Otherwise...

    Scenario 1: Picture assigned is 256x256 but the picbox is larger. Or the picbox scalemode is twips (twip sizes are greater than pixels)
    The routine will create arrays that are larger than what would be needed to read just the picture's pixels. This may still compare correctly, because the unfilled array entries will be zeroes. But it may also fail and haven't tested it. The GetDibits call requests an image height that exceeds the actual height. The return value of GetDibits is not checked to see if it is zero. If it is zero, then nothing was retrieved and the comparison would simply be comparing arrays filled with zeroes (false positive result)

    Scenario 2: Picture assigned is 256x256 but the picbox is smaller and scalemode is pixels
    The routine will not compare the entire image, only part of it.

    That routine isn't written to deal with non-pixel scalemodes and cases where the picbox is not exactly sized as the image it contains. AutoSize=True and ScaleMode=Pixels will help for loaded pictures. It is also not optimized. It should not even attempt to retrieve the pixel data if the picture sizes are not identical, but it does. If image sizes are different, then they cannot possibly be identical.
    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}

  4. #4

    Thread Starter
    Addicted Member sergeos's Avatar
    Join Date
    Apr 2009
    Location
    Belarus
    Posts
    162

    Re: Why are the two pictures not the same after Save and Load it agains?

    Well of course the size is the same. And i know about sizes, scales and units. The problem is different.

    If not difficult, make please these steps:
    • place on the Form 2 identical PictureBox with AutoRedraw = True
    • take a screenshot of the specified area into PictureBox1
    • then save image from PictureBox1
    • then load the saved image into PictureBox2
    • again make a screenshot of the same area
    • compare images


    As a result, you should leave visually 2 identical images. But only at first glance.
    Now, if you compare these two PictureBox'es, they will not be identical.
    Code:
    Private Type Rect
      Left As Long
      Top As Long
      right As Long
      bottom As Long
    End Type
    
    Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As Rect) As Long
    Private Declare Function GetDesktopWindow Lib "user32" () As Long
    
    Private Declare Function GetWindowDC Lib "user32" (ByVal hWnd As Long) As Long
    Private 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
    Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
    
    
    Private Sub GetScreenshot(Optional ByVal hWnd As Long = 0)
        Dim hDC         As Long
        
        Dim WindowRect  As Rect
        Dim Left        As Long
        Dim Top         As Long
        Dim Width       As Long
        Dim Height      As Long
    
        If hWnd = 0 Then
            'Get the DC of the desktop
            hDC = GetWindowDC(GetDesktopWindow)
        
            'Get the virtual screen coordinates (this handles multiple monitors too :)
                Left = 700
                Top = 300
                Width = 220
                Height = 130
        Else
            'Get the DC of the window we want to capture
            hDC = GetWindowDC(hWnd)
        
            'Get the window coordinates
            GetWindowRect hWnd, WindowRect
            Left = 0
            Top = 0
            Width = WindowRect.right - WindowRect.Left
            Height = WindowRect.bottom - WindowRect.Top
        End If
        
        'BitBlt into our own DC
        BitBlt PictureBox1.hDC, 0, 0, Width, Height, hDC, Left, Top, vbSrcCopy
        PictureBox1.Picture = PictureBox1.Image
    
        'Delete our reference to the windows's DC
        ReleaseDC hWnd, hDC
    End Sub
    
    Private Sub ShotSaveLoadAndCompare()
        GetScreenshot
        SavePicture PictureBox1.Picture, "C:\pic.bmp"
        PictureBox2.Picture = LoadPicture("C:\pic.bmp")
        PictureBox2.Picture = PictureBox2.Image
        Debug.Print ImagesSame(PictureBox1, PictureBox2)
    End Sub
    
    'this code return true when compare
    Private Sub TestForTrueCompare()
        GetScreenshot
        BitBlt PictureBox2.hDC, 0, 0, PictureBox1.Width, PictureBox1.Height, PictureBox1.hDC, 0, 0, vbSrcCopy
        PictureBox2.Picture = PictureBox2.Image
        Debug.Print ImagesSame(PictureBox1, PictureBox2)
    End Sub
    Last edited by sergeos; Oct 8th, 2017 at 12:25 PM.
    Ten Years After - 01 You Give Me Loving

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

    Re: Why are the two pictures not the same after Save and Load it agains?

    You don't explain what the properties/dimensions of the pictureboxes should be. Maybe you should upload a test project instead? At least we'd be able to look at your exact code and be able to explain why it failed.
    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}

  6. #6

    Thread Starter
    Addicted Member sergeos's Avatar
    Join Date
    Apr 2009
    Location
    Belarus
    Posts
    162

    Re: Why are the two pictures not the same after Save and Load it agains?

    LaVolpe, please, just copy-paste my code into Form module, and also include module with Picture compare from first topic. Thank you for your responsiveness.
    Ten Years After - 01 You Give Me Loving

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

    Re: Why are the two pictures not the same after Save and Load it agains?

    If you place a stop on the Exit For in that compare routine and test the 2 values that don't compare, you will notice something:
    1 of the bitmaps is using the alpha channel, the other is not. Therefore, the pixels are not identical
    Example:
    ? hex(lonPix_1(lonLoop)) is FFAE8F8F
    ? hex(lonPix_2(lonLoop)) is AE8F8F

    Based on the above, it appears BitBlt is setting the alpha byte in the picturebox's DC, but VB does not do 32bpp images, so it converts the image to 24bpp when it saves it. GetDIBits will return 0 as the alpha byte if the source bitmap is not 32bpp (saved bitmap), but will return it if the bitmap is 32bpp (picturebox bitmap).

    If you want to ignore the alpha channel, the compare module may need to be written to return pixels in 24bpp vs 32bpp. Of course this does require reworking the loop and sizing the array to deal with DWORD aligned bitmap scan widths. Optionally, you can still use 32bpp, but only compare the 1st 3 bytes of the value, not all four, i.e.,
    Code:
    If (lonPix_1(lonLoop) And &HFFFFFF) <> (lonPix_2(lonLoop) And &HFFFFFF) Then
    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}

  8. #8

    Thread Starter
    Addicted Member sergeos's Avatar
    Join Date
    Apr 2009
    Location
    Belarus
    Posts
    162

    Re: Why are the two pictures not the same after Save and Load it agains?

    Big thanks, LaVolpe!

    Rewritten module by me is impossible now. Not have skills. Hmmm, and what if i'm adding prefix to compair result? Like this
    ? FFAE8F8F = "FF" & AE8F8F
    Ten Years After - 01 You Give Me Loving

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

    Re: Why are the two pictures not the same after Save and Load it agains?

    Quote Originally Posted by sergeos View Post
    Rewritten module by me is impossible now. Not have skills. Hmmm, and what if i'm adding prefix to compair result? Like this
    ? FFAE8F8F = "FF" & AE8F8F
    No. The array are longs not strings. It would be ? &HFFAE8F8F = &HFF000000 OR &HAE8F8F
    But if you don't want to rewrite, simply make the change I suggested in my previous reply

    Instead of: If lonPix_1(lonLoop) <> lonPix_2(lonLoop) Then
    This: If (lonPix_1(lonLoop) And &HFFFFFF) <> (lonPix_2(lonLoop) And &HFFFFFF) Then
    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
    Addicted Member sergeos's Avatar
    Join Date
    Apr 2009
    Location
    Belarus
    Posts
    162

    Re: Why are the two pictures not the same after Save and Load it agains?

    Big thanks,
    Mustang Mach I is power!
    Ten Years After - 01 You Give Me Loving

Tags for this Thread

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