So I've got a small script which opens an image:
$file = ([System.IO.FileInfo]$FilePath);
if ($file.Exists) {
$imgInMemory = [System.Drawing.Image]::FromFile($file.FullName);
[...irrelevant code to the question...]
$imgInMemory.Save($($file.FullName '.tmp'), $codecInfo, $encoderParams);
Move-Item -Path $($file.FullName '.tmp') -Destination $file.FullName -Force;
}
So, I load the file contents with the Image.FromFile method, and I'm trying to save it back to the same filename. I have tried:
- $imgInMemory.Dispose() and $graphics.Dispose() followed by the .tmp save call and the move-item call seen above. This still gives an access denied exception.
What am I missing in terms of an open file handle because it would appear that even a -Force on the move-item only removes the .tmp file without overwriting the original file. So if you're doing something, like adding pins to an image, is it possible to save the output back to the original file? And if so, how?
CodePudding user response:
You can do this process without the need to create a temporary file, it's unclear why your code could be failing though this should work:
- Open the file to be overwritten with
ReadWrite
FileAccess. - Use the
FromStream
method on the input file.. SetFileLength
to0
for the input file before saving the new content to it.- Use either
Save(Stream, ImageCodecInfo, EncoderParameters)
orSave(Stream, ImageFormat)
overloads. - Lastly, call
Dispose
on all variables.
using namespace System.IO
using namespace System.Drawing
using namespace System.Drawing.Imaging
Add-Type -AssemblyName System.Drawing
$inFile = [FileInfo] 'path\to\file1.ext'
$refFile = 'path\to\file2.ext'
if ($file.Exists) {
$inStream = $inFile.Open([FileMode]::Open, [FileAccess]::ReadWrite)
$inImg = [Image]::FromStream($inStream)
$refImg = [Image]::FromFile($refFile)
# irrelevant code here...
$inStream.SetLength(0)
$inImg.Save($inStream, $imageCodecInfo, $encoderParams)
$refImg, $inImg, $inStream | ForEach-Object Dispose
}