Hello!
I like Arraylists. They are wonderful. You can feed them anything and they will digest it without complaining. You can add, delete, insert elements or ranges of elements without any complain and without even needing to re-dimension them. They take objects, and the objects can be of any class, images, sounds, controls, filenames..., even you can add different kinds of objects one after the other or at least a refference to it.
Don't believe me? Just press the button "Believe" and see what happens.
Anyway the purpose of this post is to highlight a situation on another program I made:
On that program I did extract the frames from a gif animation to files in a folder and then manipulated them reading and writting to disk. That was wasteful and slow. So I modified my program to do everything in memory. What do I use? Three arraylists.
This is just a sample project that won't do too much, but will give you a hint of what other things can be done.

Here I open a gif animation and dissassemble it intro frames(bitmaps). Convert them to a readable format (jpeg) and save them in an arraylist. From there I read them to show the individual frames on a picturebox. And change frames by pushing a couple of buttons, controlled by a timer, so it gives the impression of an animation.
The bitmaps in the arraylist are objects that don't have a text or name property and they have the same dimensions, so they can't easily be reordered without creating a class to use some other property. But, by using another arraylist they can be reverted in order.
My layout has a panel set to autoscroll and a picturebox set to autosize, so the image comes at normal size, but can be scrolled.
I added a subroutine for saving one frame to disk but you have to take care of the names if you want to save more frames.
Form load will create the tooltips and arraylists needed:
Imports System.IO
Imports System.Collections
Imports System.Drawing.Imaging
Imports System.Drawing.Drawing2D
Public Class Form1
Dim OriginalGif As Image
Dim PicArray1, PicArray2 As ArrayList
Dim N As Integer = 0
Dim Forward As Boolean = True
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ToolTip1.SetToolTip(btnReverse, "Will Reverse Images In The Arraylist")
ToolTip1.SetToolTip(btnBack, "Will Show Images In Reverse Sequence" & vbNewLine & "Keep It Down For Animation")
ToolTip1.SetToolTip(btnBack, "Will Show Images In Forward Sequence" & vbNewLine & "Keep It Down For Animation")
PicArray1 = New ArrayList
PicArray2 = New ArrayList
End Sub
And Menu->File->Open will open and load an animation.
Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
Dim f As New OpenFileDialog
Try
With f
.Filter = "Gif Files|*.gif"
If .ShowDialog = DialogResult.OK Then
OriginalGif = Image.FromFile(.FileName)
Rip()
pbOutput.Image = PicArray1(0)
btnBack.Enabled = True
btnForward.Enabled = True
btnReverse.Enabled = True
End If
End With
Catch ex As Exception
MessageBox.Show(ex.ToString)
Finally
If Not f Is Nothing Then
f.Dispose()
f = Nothing
End If
End Try
End Sub
Enable the controls and call the "Rip" function to dissassemble the animation and extract the frames:
Public Sub Rip()
PicArray1.Clear()
' Dim Picture As Image
Dim OrigDim As New FrameDimension(OriginalGif.FrameDimensionsList(0))
Dim FrameCount As Integer = OriginalGif.GetFrameCount(OrigDim)
' Dim MemStr As Bitmap
For i As Integer = 0 To FrameCount - 1
OriginalGif.SelectActiveFrame(OrigDim, i)
Using Frames As New Bitmap(OriginalGif)
PicArray1.Add(ConvertToRGB(Frames.Clone)) ' To avoid external code error in gdi
End Using
Next
End Sub
The "Rip" function will call the function "ConvertToRGB" that will change the format of the frames to "RGB", so they can be manipulated without getting "External error code in GDI":
Public Shared Function ConvertToRGB(ByVal original As Bitmap) As Bitmap
Dim newImage As New Bitmap(original.Width, original.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
newImage.SetResolution(original.HorizontalResolution, original.VerticalResolution)
Dim g As Graphics = Graphics.FromImage(newImage)
g.DrawImageUnscaled(original, 0, 0)
g.Dispose()
Return newImage
End Function
Now we have the bitmaps in an arraylist. What can we do with them? That is up to you.
I am only viewing them in this program and saving one individual frame. But you can do so many other things as your imagination may allow.
For viewing, the first frame is shown on the picturebox, by clicking the chevrons you could advance or reverse on the frames. If you press down and keep it down then you will see a pseudo animation, in forward or reverse, controlled by the timer:
Private Sub btnForward_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnForward.Click
'View Jpg Files in Directory
If PicArray1.Count = 1 Then Exit Sub
N += 1
If N > PicArray1.Count - 1 Then
N = 0
End If
If PicArray1(N) IsNot Nothing Then
pbOutput.Image = PicArray1(N)
End If
End Sub
Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
'View Jpg Files in Directory
If PicArray1.Count = 1 Then Exit Sub
N = N - 1
If N < 0 Then
N = PicArray1.Count - 1
End If
If PicArray1(N) IsNot Nothing Then
pbOutput.Image = PicArray1(N)
End If
End Sub
Private Sub btnForward_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnForward.MouseDown, btnBack.MouseDown
If sender Is btnForward Then Forward = True
If sender Is btnBack Then Forward = False
Timer1.Enabled = True
End Sub
Private Sub btnForward_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnForward.MouseUp, btnBack.MouseUp
Timer1.Enabled = False
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If Forward = True Then btnForward.PerformClick()
If Forward = False Then btnBack.PerformClick()
End Sub
And for saving:
Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click
Dim Str As String = "MyFile.jpg"
If Not System.IO.File.Exists(Str) Then
Try
pbOutput.Image.Save(Str, System.Drawing.Imaging.ImageFormat.Jpeg)
'PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Png)
Catch Ex As Exception
MessageBox.Show("Could Not Write To Location " & Ex.ToString)
End Try
End If
End Sub
It will create a file in your program directory.
I also added a subroutine to revert the order of the frames. So when yo press the chevron to advance, the animation will reverse, and so will the other button. Here you see how I reversed the frames:
Private Sub btnReverse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReverse.Click
PicArray2.Clear()
For i As Integer = PicArray1.Count - 1 To 0 Step -1
PicArray2.Add(PicArray1(i))
Next
PicArray1.Clear()
For Each obj As Object In PicArray2
PicArray1.Add(obj)
Next
pbOutput.Image = PicArray1(0)
pbOutput.Refresh()
End Sub
That is it. Please check the attached project sample.
The code for the believe button is in the project.
Thank you.
Attached File(s)
-
InMemory.zip (30.88K)
Number of downloads: 354





MultiQuote



|