使用Powershell的多页TIFF出现问题 - 保存添加“GDI+中发生一般错误
本文关键字:GDI+ 添加 错误 保存 Powershell TIFF 问题 使用 | 更新日期: 2023-09-27 18:33:48
我似乎无法让PowerShell将SaveAdd方法用于多页TIFF。在我开始收到关于片段毫无意义的批评之前,这是一个更大脚本的一部分,只是我为完成 TIFF 图像处理而创建的测试平台。所以我在这里要做的只是将多页 TIFF 转换为位深度为 1、分辨率为 200 ppi 的新多页 TIFF(原始脚本中的一些包袱仍然存在(。
我遇到的唯一问题是SaveAdd()
方法。我确信我忽略了一些简单的东西。由于很少有TIFF资源可供PowerShell仔细阅读,我的大部分资源都是C#,因此在平台差异中可能缺少一些东西。我尝试使用流,如此处使用。 我还引用了 MSDN 的示例、Bob Powell 的示例以及此处"GDI+ 中发生一般错误"的每个问题。
我已经能够为第一帧(页面(获得几乎所有方法,但我总是在其他页面上收到相同的错误。
这是代码(将其保存在具有多页TIFF的文件夹中并执行(:
Function Test-Image{
[cmdletbinding()]
param(
)
#Image Resolution in DPI
$ImageRes = 200
$ImageQuality = 100 # %
$ImageBitDepth = 1 # ColorDepth
$FileObjects = Get-ChildItem -File -Recurse -Exclude "Test-Image.ps1"
$ImageFiles = ($FileObjects | Where-Object {".bmp",".gif",".jpg",".jpeg",".png",".tif",".tiff",".wmf" -eq $_.Extension -and !$_.PSIsContainer -and $_.fullname -notlike "$DropBoxPath'UnsupportedFiles'*"}).fullname
#Process Image Files
$imageCodec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() |Where-Object {$_.MimeType -eq "image/tiff"}
$encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(3)
$encoderParams.Param[1] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality, $ImageQuality)
$encoderParams.Param[2] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::ColorDepth, $ImageBitDepth)
foreach ($ImageFile in $ImageFiles) {
#Load the Image
$SourceImage = New-Object System.Drawing.Bitmap($ImageFile) -EV e
If ($e.Count -eq 0) {
#Generate Random File Name
$NewFileName = "$([System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetRandomFileName())).tif"
$FrameCount = $SourceImage.GetFrameCount($SourceImage.FrameDimensionslist[0])
# Make sure we start on the First Frame (Page)
$SourceImage.SelectActiveFrame($SourceImage.FrameDimensionsList[0],0) | Out-Null
#Create the New Tiff and load the first Frame.
$NewImage = New-Object System.Drawing.Bitmap($SourceImage)
$NewImage.setResolution($ImageRes,$ImageRes)
for ($FrameIndex=0; $FrameIndex -lt $FrameCount; $FrameIndex++) {
write-host "Processing $ImageFile Page $($FrameIndex + 1) of $FrameCount" #| Out-File -Append -FilePath $LogFile
If ($FrameIndex -eq 0) {
#First Page
# Set Save Flag to MultiFrame
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag,"MultiFrame")
# Save the First Frame (Page)
$NewImage.Save("$([System.IO.Path]::GetDirectoryName($ImageFile))'$NewFileName",$imageCodec,$encoderParams)
} Else {
#Additional Pages
# Set the Current Frame
$SourceImage.SelectActiveFrame($SourceImage.FrameDimensionsList[0],$FrameIndex) | Out-Null
# Switch Save Flag to add Frame
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag,"FrameDimensionPage")
$NewImage.SaveAdd($SourceImage,$encoderParams)
}
}
# Cleanup
$SourceImage.Dispose()
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag,"Flush")
$NewImage.SaveAdd($encoderParams)
$NewImage.Dispose()
#Remove-Item -Path $ImageFile -Force
} Else {
write-host "$ImageFile Could not be opened." | Out-File -Append -FilePath $LogFile
}
}
#Clear Variable
Remove-Variable ImageFiles
}
Test-Image
以下是错误,我假设这些错误是由相同的问题引起的:
Exception calling "SaveAdd" with "2" argument(s): "A generic error occurred in GDI+."
At V:'jshaw'My Pictures'test'Test-Image.ps1:48 char:6
+ $NewImage.SaveAdd($SourceImage,$encoderParams)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ExternalException
Exception calling "SaveAdd" with "1" argument(s): "A generic error occurred in GDI+."
At V:'jshaw'My Pictures'test'Test-Image.ps1:54 char:4
+ $NewImage.SaveAdd($encoderParams)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ExternalException
我现在尝试从我的 PowerShell 脚本中执行以下 C# 代码,但出现相同的错误。请记住,这是我第一次尝试 C#。我只是更改了 MSDN 示例以满足我的需求。
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace jshaw
{
public class MultiFrame_Tiff
{
public static void Process_Tiff(string ImageFile)
{
Bitmap SourceImage;
Bitmap NewImage;
ImageCodecInfo myImageCodecInfo;
Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;
// Create three Bitmap objects.
SourceImage = new Bitmap(ImageFile);
SourceImage.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page,0);
NewImage = new Bitmap(SourceImage);
// Create New File Name
string NewFileName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) + ".tif";
// Get an ImageCodecInfo object that represents the TIFF codec.
myImageCodecInfo = GetEncoderInfo("image/tiff");
// Create an Encoder object based on the GUID
// for the SaveFlag parameter category.
myEncoder = Encoder.SaveFlag;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
myEncoderParameters = new EncoderParameters(1);
// Save the first page (frame).
myEncoderParameter = new EncoderParameter(myEncoder,(long)EncoderValue.MultiFrame);
myEncoderParameters.Param[0] = myEncoderParameter;
NewImage.Save(NewFileName, myImageCodecInfo, myEncoderParameters);
int FrameCount = SourceImage.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
for (int i = 1; i < FrameCount;i++)
{
SourceImage.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page,FrameCount);
// Save the second page (frame).
myEncoderParameter = new EncoderParameter(myEncoder,(long)EncoderValue.FrameDimensionPage);
myEncoderParameters.Param[0] = myEncoderParameter;
NewImage.SaveAdd(SourceImage, myEncoderParameters);
}
// Close the multiple-frame file.
myEncoderParameter = new EncoderParameter(myEncoder,(long)EncoderValue.Flush);
myEncoderParameters.Param[0] = myEncoderParameter;
NewImage.SaveAdd(myEncoderParameters);
}
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for(j = 0; j < encoders.Length; ++j)
{
if(encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
}
}
所以显然"编码器参数(编码器,字符串("构造函数的实现有问题。 更改这些行以使用"EncoderParameter(Encoder,Int("构造函数就可以了。
所以下面几行:
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag,"MultiFrame")
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag,"FrameDimensionPage")
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag,"Flush")
应该是这个:
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag, [int][System.Drawing.Imaging.EncoderValue]::MultiFrame)
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag, [int][System.Drawing.Imaging.EncoderValue]::FrameDimensionPage)
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::SaveFlag, [int][System.Drawing.Imaging.EncoderValue]::Flush)