Page 1 of 1

Usage of streams

Posted: Fri Jun 07, 2013 12:04 pm
by serrut
Hi,

What is the best practise for viewing & modifying images in a Vintasoft ImageViewer component?

Do I need to keep the stream to the image open or close it?

In the documentation I found following code:

Code: Select all

Dim images As ImageCollection = New ImageCollection()
Dim fStream As FileStream = New FileStream("multipage.tif", FileMode.Open, FileAccess.ReadWrite)
Dim images As ImageCollection images = New ImageCollection
images.Add(fStream)
If I close the file stream, an exception (below you can find the trace) occurs in the ImageViewer component: cannot access a closed file.
As I use a lot of ImageViewer components in my application gui, I need to keep a lot of streams open, which I don't like!

Code: Select all

   at System.IO.__Error.FileNotOpen()
   at System.IO.FileStream.Seek(Int64 offset, SeekOrigin origin)
   at System.IO.FileStream.set_Position(Int64 value)
   at Vintasoft.Imaging.Codecs.ImageFileSource.set_Position(Int64 value)
   at Vintasoft.Imaging.Codecs.Tiff.TiffTag.()
   at ..()
   at ..()
   at Vintasoft.Imaging.Codecs.Tiff.TiffPage.GetStripGrid()
   at Vintasoft.Imaging.Codecs.TiffDecoder.GetImageRectGrid(Int32 pageIndex)
   at Vintasoft.Imaging.ImageRendering.ImageRenderer..ctor(DecoderBase decoder, Int32 pageIndex)
   at Vintasoft.Imaging.ImageRendering.ImageRenderer..ctor(VintasoftImage image)
   at ..6(VintasoftImage )
   at Vintasoft.Imaging.ImageViewer.(VintasoftImage , Boolean )
   at Vintasoft.Imaging.ImageViewer.(VintasoftImage , Boolean )
   at ..81()
   at ..()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
Thanks for your replies.

Re: Usage of streams

Posted: Fri Jun 07, 2013 1:26 pm
by Alex
Hello Tom,

If you want to view and modify images from files in the ImageViewer, the best practice is

1. Open file in read-write mode and get reference to the image stream

Code: Select all

Dim fStream As FileStream = New FileStream("multipage.tif", FileMode.Open, FileAccess.ReadWrite)
2. Add image stream to the image collection of ImageViewer

Code: Select all

imageViewer1.Images.Add(fStream)
3. View and modify images in image collection of ImageViewer

Code: Select all

imageViewer1.Images(0).Rotate(90)
4. Remove image from collection and close the image stream when image is not necessary any more

Code: Select all

For i = 0 To imageViewer1.Images.Count - 1
  imageViewer1.Images(i).SourceInfo.Stream.Close()
Next i

imageViewer1.Images.ClearAndDisposeItems()
Best regards, Alexander

Re: Usage of streams

Posted: Fri Jun 07, 2013 2:41 pm
by serrut
Hi Alex,

Thank you for your answer. Your code helps me to not store the stream in my object, which I like.
BUT ... if I have 100 ImageViewers, I still have 100 file streams open. Right?

I have always learned to close a stream as soon as possible. If you want to modify again, just initialize (open) the stream again, do the modification and close it again ...

In a previous version of Vintasoft Imaging (4.3), the internal logic must have been different:

Code: Select all

Dim image as VintaSoftImage = new VintaSoftImage("C:/temp/test.tiff")
imageViewer.Image = image
This code block was working perfectly, and no lock was left on my file. This is expected behavior. But since 6.1, the lock on the file stays ...

Re: Usage of streams

Posted: Fri Jun 07, 2013 3:01 pm
by serrut
I also want to notice we add ImageViewer's dynamically to our VB.NET application form. Images are retrieved from a scanner, or a file import (PDF for example).
I just created a test project which has a form and a button "btnAddImageViewer". When you click the button, the application will crash => "Cannot access a closed file"

Code: Select all

 Private Sub btnAddImageViewer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddImageViewer.Click
        ' Create image viewer
        Dim imageViewer As ImageViewer = New ImageViewer()
        imageViewer.Location = New Point(100, 100)
        imageViewer.Size = New Size(200, 200)

        ' Add image to image viewer
        Dim fstream As FileStream = Nothing
        Try
            fstream = New FileStream("c:/temp/test.tiff", FileMode.Open, FileAccess.Read)
            imageViewer.Images.Add(fstream)
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            If (fstream IsNot Nothing) Then
                Try
                    fstream.Close()
                Catch ex As Exception
                    MsgBox(ex.Message)
                End Try
            End If
        End Try

        ' Add image viewer to form
        Me.Controls.Add(imageViewer)
    End Sub