0

I am writing a WinForm application using VS2010 & VS2012 with .Net4.

In the application I load individual images into pictureboxes and then delete those images the user does not wish to keep.

Every time I try to delete these "unwanted" images I get the above error message:

"The process cannot access the file xxxxxx because it is being used by another process"

The following is used to load an image into a dynamically created picturebox together with the code to delete the unwanted images.

Option 1:

Load Image:

picBox.Image = Image.FromFile(imgInfo.FullName).GetThumbnailImage(128, 128, Nothing, Nothing)

Delete Image:

For Each imgFile As String In Directory.GetFiles(imgSharedFolder)
   File.Delete(imgFile)
Next imgFile

Option 2:

Since loading an image file into a picturebox will "lock" the image file I tried the following by reading the image file into a FileStream and then Close the FileStream after loading the image into the picturebox

Load:

fs = New System.IO.FileStream(imgInfo.FullName, IO.FileMode.Open, IO.FileAccess.Read)
picBox.Image = System.Drawing.Image.FromStream(fs).GetThumbnailImage(128, 128, Nothing, Nothing)
fs.Close()

Delete:

Dim picList As String() = Directory.GetFiles(imgSharedFolder, "*.jpg")
For Each f As String In picList
   File.Delete(f)
Next f

I get the same error message.

Option 3:

After some more searching, reading and trying I came across this suggestion to create an image object and then Dispose of the image object once the image is loaded into the picturebox:

Load:

Dim newImage As Image
newImage = Image.FromFile(imgInfo.FullName).GetThumbnailImage(128, 128, Nothing, Nothing)
picBox.Image = newImage

Unfortunately I just got the same error message.

Is there any other possible solution to this problem, something I may have overlooked ?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Tino Fourie
  • 59
  • 1
  • 2
  • 10
  • @PorkChop: Look again, the FS.Close is on the 3rd line of the Load function in Option 2. – Tino Fourie Jun 02 '14 at 18:15
  • 1
    possible duplicate of [how to prevent the Image.FromFile() method to lock the file](http://stackoverflow.com/questions/18250848/how-to-prevent-the-image-fromfile-method-to-lock-the-file) – pmcoltrane Jun 02 '14 at 18:15
  • @pmColtrane: Looking at your link now. Thanks for that as it is very comprehensive and detailed. On face value it almost looks like a duplicate... (only a duplicate if the solution proposed works xD ) – Tino Fourie Jun 02 '14 at 18:21

1 Answers1

0

Here is the solution to the problem I had, posted above.

Although I was reading image files into pictureboxes, I neglected to to remind myself that I do a very similar process when saving the images to a Database.

Only after I started breaking up everything that was happening between reading images into picboxes and writing them to the DB I managed to find the correct approach to the problem.

Here is the process of reading image files into pictureboxes:

    For Each imgFile As String In Directory.GetFiles(fbdGetImagesOnDisk.SelectedPath)
       Try
          Dim fs As System.IO.FileStream
          imgInfo = New FileInfo(imgFile)
          If myext.Contains(LCase(imgInfo.Extension)) Then
             'Create dynamic picturebox
             picBox = New PictureBox()

             'Specify a valid picture file path
             fs = New System.IO.FileStream(imgInfo.FullName, IO.FileMode.Open, IO.FileAccess.Read)
             picBox.Image = System.Drawing.Image.FromStream(fs).GetThumbnailImage(128, 128, Nothing, Nothing)
             fs.Close()
   Catch ex as Exception
      msgbox(ex.message)
   End Catch
   Next imgFile

The following code is to write an image from disk to DB before deleting the image file on disk. IMPORTANT: Notice where the fs.Close() is because if it is place incorrectly it will generate GDI+ Generic Errors and fail to delete the very last image.

Try
   conn.Open()
   'Create a FileStream for the image file on disk. This will allow us to Close the stream and release the file lock
   Dim fs As System.IO.FileStream
   'Specify a valid picture file path
   fs = New System.IO.FileStream(imgPath & "\" & imgName, IO.FileMode.Open, IO.FileAccess.Read)
   'Create an Image object to store the image.
   Dim img As Image = Image.FromStream(fs)
   'Create a Thumbnail object to store the Thumbnail of the image (128,128)
   Dim imgThumbnail As Image = Image.FromStream(fs).GetThumbnailImage(128, 128, Nothing, Nothing)
   'Create an empty stream in memory for the Image.
   Dim imgStream As New IO.MemoryStream
   'Create an empty stream in memory for the Thumbnail of the image
   Dim tmbStream As New IO.MemoryStream
   'Fill the stream with the binary data from the Image.
   img.Save(imgStream, Imaging.ImageFormat.Jpeg)
   'Fill the empty stream with the data of the Thumbnail
   imgThumbnail.Save(tmbStream, Imaging.ImageFormat.Jpeg)
   'Store Image memory stream as array
   Dim arrImage() As Byte = imgStream.GetBuffer()
   'Store Thumbnail memory stream as array
   Dim arrThumbnail() As Byte = tmbStream.GetBuffer()
   'Close the streams
   imgStream.Close()
   tmbStream.Close()
   'Close the File Stream
   **fs.Close()**

   With cmd
      .CommandText = SQLstr
      .Connection = conn
      .Parameters.Clear()
      .Parameters.AddWithValue("@imgName", imgName)
      .Parameters.AddWithValue("@imgImage", arrImage)
      .Parameters.AddWithValue("@imgThumbnail", arrThumbnail)
      .Parameters.AddWithValue("@patID", CInt(patID))
      .Parameters.AddWithValue("@conID", CInt(conID))
      .ExecuteNonQuery()
   End With

   Return True

Catch ex As Exception
   MsgBox(ex.Message)
   Return False
End Try
conn.Close() 'Close DB connection

After the image is written ti the DB we can now begin with removing the images files on disk without getting any error message about the file being locked. Herewith the code to delete the image file from disk after it was written to the DB:

Try
   Dim picList As String() = Directory.GetFiles(imgSharedFolder, "*.jpg")
   For Each f As String In picList
      File.Delete(f)
   Next f
Catch ex As Exception
   MsgBox(ex.Message)
End Try

Thanks to those who replied as it reconfirmed with a lot of information behind the process and why it should be done in a specific manner. Without your help and guidance I would have been stuck for a little while longer.

Tino Fourie
  • 59
  • 1
  • 2
  • 10