Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Display 100's of Images

Status
Not open for further replies.

Error7

Programmer
Jul 5, 2002
656
GB
Can anybody suggest a more efficient way of doing this.

My main programme can load multiple images into a picture box sequentially, sizing the Picture box according to the limitations of the graphics card memory. So with 256 MB of memory I can achieve a picture box 4 x 4 of the screen size.

I now want to give the users the ability to rearrange their photo's before adding them to the picture box and to do this I have a form which equals the screen size and I add each of the users selected photo's into an image box. Loading and resizing the image boxes as I go.

This is my code that loads the Image Boxes:

Code:
Dim i As Integer
Dim a As Integer
Dim Count As Integer
Dim X1 As Long, Y1 As Long
Me.MousePointer = vbHourglass
On Error GoTo ErrHandler

For i = 0 To frmMain.lstFiles.ListCount - 1    
    DoEvents    
    Fname = frmMain.lstFiles.List(i)
    
    With Image1(a)
        .Visible = True
        .Picture = LoadPicture(Fname)
        .Width = PicWidth
        .Height = PicHeight
        .Left = X1
        .Top = Y1
    End With
    
    X1 = X1 + PicWidth
    Count = Count + 1
    
    If Count >= NumWide Then
        Count = 0
        X1 = 0
        Y1 = Y1 + (PicHeight)
    End If
    
    a = a + 1
    Load Image1(a)
    End If
Here:
Next i

Me.MousePointer = vbDefault

My problem is that if the user selects a couple of hundred photos then the whole thing starts to bog down and gets slower and slower until it eventually bombs out on an Error 7.

Can this be done more efficiently or do I need to have a re-think about what I am trying to achieve.

Thanks in advance.

Alan

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Oh, and you can delete the Image1_OLEStartDrag sub; it comes from an earlier iteration of the code and is not needed in this version
 
Sorry Mike, I'm stuck.

I moved your code from the Form Refresh and put it behind a command button for testing.

I also included a Dir and File ListBox.

I then added a loop to load individual images and lay them out sequentially across the form as so...

Code:
For i = 0 To File1.ListCount - 1
    
        Set myPic = LoadPicture(Dir1.List(Dir1.ListIndex) & "\" & File1.List(i))
    
        For lp1 = 0 To PicsX
            For lp2 = 0 To PicsY
                lp = lp2 * PicsX + lp1
                myPic.Render Form1.hDC, lp1 * Form1.ScaleWidth / PicsX, lp2 * Form1.ScaleHeight / PicsY, Form1.ScaleWidth / PicsX, Form1.ScaleHeight / PicsY, 0&, myPic.Height, myPic.Width, -myPic.Height, 0&
            Next
        Next
        
    Next i
But this only displays the last image from the File List.


[gray]Experience is something you don't get until just after you need it.[/gray]
 
Well, actually it loads and displays all of them - each one overlaying the previous layout ...

What you really need to do is to drop the lp1 and lp2 loops and calculate them from the value of i - or drop the i loop and calculate i from the values of lp1 and lp2 (which is more-or-less lp). Then the LoadPicture needs to go just before the .Render line.
 
That makes sense. I shall try it later.

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Remember, I'm just providing suggestions for how you can approach this, not an actual solution ...
 
Yes. I have to admit that I jumped in feet first when I got home last night and didn't have sufficient time to study your code. I just wanted to see how it handled multiple 1.5 MB jpg's so cobbled together the Dir loop.

Code:
For i = 1 to 100
    Debug.Print "I must be more patient"
Next i

Thanks

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Mike, I have modified your code so that it loads individual images and lays them out on the Form sequentially.

This is the code:

Code:
If Not InResize Then
    InResize = True
    Form1.Cls
 
    For yPos = 0 To PicsY
        For xPos = 0 To PicsX
            Set myPic = LoadPicture(Dir1.List(Dir1.ListIndex) & "\" & File1.List(i))
            myPic.Render Form1.hDC, xPos * Form1.ScaleWidth / PicsX, yPos * Form1.ScaleHeight / PicsY, Form1.ScaleWidth / PicsX, Form1.ScaleHeight / PicsY, 0&, myPic.Height, myPic.Width, -myPic.Height, 0&
            i = i + 1
        Next
    Next
    
    InResize = False
End If

Loading 64 1.5 MB images takes 26 seconds as opposed to 15 seconds using my previous method.

Am I doing something wrong?


[gray]Experience is something you don't get until just after you need it.[/gray]
 
Well, as I said it's unoptimised. Right now we are doing a bunch of calculations (and accessing object properties) for every iteration of the loop - every single one of which can be precalculated:

xPos * Form1.ScaleWidth / PicsX
yPos * Form1.ScaleHeight / PicsY
Form1.ScaleWidth / PicsX
Form1.ScaleHeight / PicsY
myPic.Height
myPic.Width
-myPic.Height

Having said that, I'm very surprised at the time difference




 
I've just done a couple more tests.

If I rem out the line myPic.Render... it still takes 26 seconds to load the 64 images, but if I move the LoadPicture line out of the loop then the same image gets rendered 64 times in less than two seconds.


[gray]Experience is something you don't get until just after you need it.[/gray]
 
As I said way back near the beginning, my code
strongm said:
can resize and display 1024 1.4Mb images on a form in less than 1/4 of a second - as long as the full-size images are preloaded (yes, I know we run in to a memory problem if we try and actually load 1024 full size images, so the example resizes and displays the same image 1024 times). But it takes about 15 seconds or so if I have to load an image each time.

Which is in line with your observations. I am however surprised that it is slower than the image/picture/image version ...
 
Well thanks for your input anyway. It was an interesting exercise which I think confirms that the bottleneck is in the image loading.

If there was a way of loading and resizing the picture into the Clipboard before adding to the array of Image Controls it might be quicker but I can't see a way of doing this.

Thanks

[gray]Experience is something you don't get until just after you need it.[/gray]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top