Overwriting image metadata

  • Thread starter Thread starter Tim Kelley
  • Start date Start date
T

Tim Kelley

I need to read the metadata of an image, display it on the screen and allow
the user to change it and then re-write the metadata back into the image.
The issue I am having is if I try to rename or delete the existing image
before re-writing the image file I get an error stating that the image is in
use. I am using Image.FromFile() to read the file. I have tried disposing
of the image and running the garbage collector (GC.Collect()), but it still
doesn't work. Is there a way to actually close the file so I can
delete/rename it?

Thanks,

Tim
 
Here is the code snippet:

Image targetImg;

targetImg = Image.FromFile("O:\\xxxx\\xx\\xxxx\\xxx\\xxxx\\0004.jpg");

targetImg.Dispose();

GC.Collect();

targetImg = null;

Thanks for your help,



Tim
 
Tim said:
Here is the code snippet:

A snippet isn't a complete example. Your code doesn't show any metadata
editing, renaming or deleting, and doesn't compile when pasted into a
file and passed to csc.
Image targetImg;

targetImg = Image.FromFile("O:\\xxxx\\xx\\xxxx\\xxx\\xxxx\\0004.jpg");

GDI+ (which Image is part of) does indeed keep a handle to the file on
disk open for as long as the image isn't disposed, when you load from a
file, as I recall.
targetImg.Dispose();

GC.Collect();

This isn't recommended, and won't have an effect on your problem here.
For one thing, you've already disposed the image, so you won't be
getting the benefit of finalization (for which
GC.WaitForPendingFinalizers() would be a better choice, anyhow), and
secondly, the targetImg object is still rooted, as you don't null it out
until after calling the GC, so it itself won't be collected.
targetImg = null;

Here's a complete example which successfully opens, disposes and renames
an image:

---8<---
using System;
using System.IO;
using System.Drawing;

class App
{
static void Main(string[] args)
{
Image img = Image.FromFile(args[0]);
img.Dispose();
File.Move(args[0], args[0] + ".2");
}
}
--->8---

Here's the results of the code running on my system, showing that the
image was successfully renamed:

---8<---
/c/proj/rename-after-open$ d
OpenAndRename.cs OpenAndRename.exe test.jpg
/c/proj/rename-after-open$ ./OpenAndRename.exe test.jpg
/c/proj/rename-after-open$ d
OpenAndRename.cs OpenAndRename.exe test.jpg.2
/c/proj/rename-after-open$
--->8---

Now, if you want to rename or delete the image while it's still open,
then (IIRC) you'll have to load the image's data into memory first
(consider using MemoryStream), then load the image from the
MemoryStream, so that GDI+ doesn't have any way to keep the file on disk
open. Alternatively, consider using a FileStream with appropriate
sharing flags (FileShare enumeration in overloaded FileStream
constructor) and pass that to Image.FromStream.

-- Barry
 
Back
Top