使用图片时出现问题:参数无效

7

这一切始于我在Stackoverflow上找到的非常有用的代码片段

然后,我决定进行自己的调整,并将图像大小调整功能添加到此方法中。 然而,在与这个问题斗争后,我现在得到的信息是:"参数无效"

我还想强调,尽管出现错误,但图片已经成功上传。 但是,它们没有按预期进行优化。


这是我"上传按钮"中的代码部分:

fuOne.SaveAs(Server.MapPath("~/imgFolder/temp/") + fuOne.FileName);

System.Drawing.Image imgUploaded = System.Drawing.Image.FromFile(Server.MapPath("~/imgFolder/temp/") + fuOne.FileName);

SaveJpeg(Server.MapPath("~/imgFolder/temp/") + fuOne.FileName, imgUploaded, 60, 300, 300);

这是我SaveJpeg方法的完整代码:
public static void SaveJpeg(string path, System.Drawing.Image imgUploaded, int quality, int maxWidth, int maxHeight)
    {
        if (quality < 0 || quality > 100)
            throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");

        // resize the image
        int newWidth = imgUploaded.Width;
        int newHeight = imgUploaded.Height;
        double aspectRatio = (double)imgUploaded.Width / (double)imgUploaded.Height;

        if (aspectRatio <= 1 && imgUploaded.Width > maxWidth)
        {
            newWidth = maxWidth;
            newHeight = (int)Math.Round(newWidth / aspectRatio);
        }
        else if (aspectRatio > 1 && imgUploaded.Height > maxHeight)
        {
            newHeight = maxHeight;
            newWidth = (int)Math.Round(newHeight * aspectRatio);
        }


        Bitmap newImage = new Bitmap(imgUploaded, newWidth, newHeight);

        Graphics g = Graphics.FromImage(imgUploaded);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        g.DrawImage(imgUploaded, 0, 0, newImage.Width, newImage.Height);

        g.Dispose();
        imgUploaded.Dispose();

        // Lets start to change the image quality
        EncoderParameter qualityParam =
            new EncoderParameter(Encoder.Quality, quality);
        // Jpeg image codec 
        ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");

        EncoderParameters encoderParams = new EncoderParameters(1);
        encoderParams.Param[0] = qualityParam;

        System.Drawing.Image imgFinal = (System.Drawing.Image)newImage;
        newImage.Dispose();

        imgFinal.Save(path, jpegCodec, encoderParams);
        imgFinal.Dispose();
    }

    /// <summary> 
    /// Returns the image codec with the given mime type 
    /// </summary> 
    private static ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        // Get image codecs for all image formats 
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

        // Find the correct image codec 
        for (int i = 0; i < codecs.Length; i++)
            if (codecs[i].MimeType == mimeType)
                return codecs[i];
        return null;
    } 

跟进

看起来代码有几个错误。一个是编码问题,另一个是图像保存问题。

Aristos的跟进对解决这个问题非常重要,因为它可以修复我保存文件时犯下的低级错误。


3
这个问题可能与以下问题相关:https://dev59.com/YEbRa4cB1Zd3GeqPww8u - Larry
@Laurent 谢谢。我还在努力解决这个问题,但现在我可以借助你的链接来帮助我了。 - Marco
4个回答

9

当您保存图像时,我建议更正确的做法是:

ImageCodecInfo myImageCodecInfo = FindJpegEncoder();

EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, cQuality);

imgFinal.Save(TheFileNameTosaveIt, myImageCodecInfo, encoderParameters);

这是从系统中查找编码器的函数。
internal static ImageCodecInfo FindJpegEncoder()
{
    // find jpeg encode text
    foreach (ImageCodecInfo info in ImageCodecInfo.GetImageEncoders())
    {
        if (info.FormatID.Equals(ImageFormat.Jpeg.Guid))
        {
            return info;
        }
    }

    Debug.Fail("Fail to find jPeg Encoder!");
    return null;
}

请确保long cQuality = 65L是一个长整型,我认为实际上只需要将函数调用中的int改为long。另外,最好使用using(){}来包装需要dispose()的函数。

跟进

在尝试保存新图像时,您有一个错误,您没有从之前创建的实际图形中获取它,这就是为什么没有任何变化的原因。您实际上并没有保存创建的图像而是创建了一个新的图像,所以这段代码:

System.Drawing.Image imgFinal = (System.Drawing.Image)newImage;
newImage.Dispose();

imgFinal.Save(path, jpegCodec, encoderParams);
imgFinal.Dispose();

必须是
newImage.Save(path, jpegCodec, encoderParams);
newImage.Dispose();

感谢您的帖子。然而,使用您的建议后,我仍然没有任何进展。图像仍在上传(但未调整大小或降低质量)。因此,基本上,在应用您的更改后,我仍然处于同一位置。 :( - Marco
@Marco 你说出现了错误,而不是图像没有应用任何更改地显示。 - Aristos
也许我没有正确地解释自己。抱歉。我的意思是:如原帖所述,“参数无效”信息仍在显示。正如您可以在原帖中阅读到的那样:“尽管出现错误,但图像已成功上传。然而,它们并没有像预期的那样被优化。”。 - Marco

5
在我的情况下,我在调用Save之前不小心调用了Dispose,导致出现相同的“参数无效”错误。
希望这可以帮到你!

5

我通过指定Quality的数据类型来解决了这个问题。它必须是“long”类型,因此这解决了我的问题。

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$bmp = New-Object System.Drawing.Bitmap $imagePath

#Encoder parameter for image quality 
$myEncoder = [System.Drawing.Imaging.Encoder]::Quality
$encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1) 
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($myEncoder, [long]$quality)

# get codec
$myImageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()|where {$_.MimeType -eq 'image/jpeg'}

#save to file
$bmp.Save($imageOutPut,$myImageCodecInfo, $($encoderParams))

没有使用“long”,会出现如下错误信息:
Exception calling "Save" with "3" argument(s): "Parameter is not valid."
At C:\Projects\Image_Comparison\ImageComparison.ps1:81 char:49
+     $bmp.Save($imageOutPut,$myImageCodecInfo, $($encoderParams))
+                                                 ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

1
因为我在C#上遇到了相同的问题,所以点赞。 - Aske B.

0
在我的情况下,与示例类似,问题是quality变量是一个int类型,但需要是long类型。这就是为什么它返回“参数无效”的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接