使用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;
        }
    }
}

使用Powershell的多页TIFF出现问题 - 保存添加“GDI+中发生一般错误

所以显然"编码器参数(编码器,字符串("构造函数的实现有问题。 更改这些行以使用"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)