Various ways to display multiple photographs: Using Rects and thumbs
My prior post showed how to use an array of PictureBox controls to display multiple photographs on a form. Now we’ll do something similar, but instead of using the PictureBox control, which is a little bit heavyweight, we can just draw directly onto the form.
This code uses a foxpro table of already created thumbnails (see Create thumbnails of all your digital photos in a single table) as a source. The Foxpro memo field is automagically an array of bytes, from which we can create a memory stream, which can be used by the Bitmap constructor.
Note how the Paint event is passed a ClipRectangle which indicates what subset of the form needs to be painted.
For some reason, the Rectangle’s Left property is readonly, so we have to set the Location property.
Try changing the DoubleBuffered property and move a small window around over the form to force parts to redraw.
Next post: do it on a Fox form.
Imports System.Data.OleDb
Public Class Form1
Dim xpix As Integer = 8
Dim ypix As Integer = 8
Dim aPic(xpix, ypix) As PictureBox
Dim dt As New DataTable
Dim PixPath As String = "d:\pictures\"
Dim PicPageIndex As Integer = 0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim da As New OleDb.OleDbDataAdapter("Select fullname,thumb from pixthumb where LEFT(fullname,7)='2006\08'", _
"provider=vfpoledb.1;data source=" + PixPath + "pixthumb.dbf")
da.Fill(dt)
Me.WindowState = FormWindowState.Maximized
Me.DoubleBuffered = True ' Try changing this: move a small window around on top of the form to force Paint msgs to see
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim x, y As Integer
Dim r As New Rectangle
Dim w, h As Integer
Dim loc As New Point
For y = 0 To ypix - 1
For x = 0 To xpix - 1
w = Me.Width / xpix
h = Me.Height / ypix
r.Width = w
r.Height = h
loc.X = x * w
loc.Y = y * h
r.Location = loc
If r.IntersectsWith(e.ClipRectangle) Then
Dim nIndex As Integer = PicPageIndex + y * ypix + x
If nIndex >= 0 And nIndex >= dt.Rows.Count Then
e.Graphics.FillRectangle(Brushes.AntiqueWhite, r)
Else
Dim ThumbBytes() As Byte = dt.Rows(nIndex).Item(1)
Dim ostream As New IO.MemoryStream(ThumbBytes)
Dim bm As New Bitmap(ostream)
e.Graphics.DrawImage(bm, r)
End If
End If
Next
Next
End Sub
Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
Select Case Char.ToUpper(e.KeyChar)
Case "Q" 'Quit
End
Case "N"
If PicPageIndex < dt.Rows.Count Then
PicPageIndex += (xpix - 1) * (ypix - 1)
End If
Case "P"
If PicPageIndex > 0 Then
PicPageIndex -= (xpix - 1) * (ypix - 1)
End If
End Select
Me.Invalidate()
End Sub
Private Sub Form1_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd
Me.Invalidate()
End Sub
End Class