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
ReadWriteFileAccess. - Use the
FromStreammethod on the input file.. SetFileLengthto0for the input file before saving the new content to it.- Use either
Save(Stream, ImageCodecInfo, EncoderParameters)orSave(Stream, ImageFormat)overloads. - Lastly, call
Disposeon 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
}
