繁体   English   中英

使用 powershell 处理多页 TIFF 时遇到问题 - SaveAdd“GDI+ 中发生一般错误。”

[英]Trouble with multipage TIFF using powershell - SaveAdd “A Generic error occurred in GDI+.”

我似乎无法让 PowerShell 将 SaveAdd 方法用于多页 TIFF。 在我开始收到关于片段毫无意义的批评意见之前,这是一个更大脚本的一部分,并且只是我创建的一个测试平台,用于通过 TIFF 图像处理工作。 所以我在这里要做的就是将多页 TIFF 转换为位深度为 1 和分辨率为 200 ppi 的新多页 TIFF(原始脚本中的一些包袱仍然存在)。

我遇到的唯一问题是SaveAdd()方法。 我确信我忽略了一些简单的事情。 由于可供 PowerShell 阅读的 TIFF 资源很少,我的大部分资源都是 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, String)”构造函数的实现有问题。 更改这些行以使用“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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM