参数在Image.Save上无效

时间:2016-08-20 23:31:30

标签: c# image base64

这里有人能看错吗?我在'imageData.Save'行上得到一个“参数无效”,但是我怀疑imageData var早于它,因为我在imageData对象设置后看到了一些参数异常。感谢您的任何建议。

    using (Image image = Image.FromFile(Server.MapPath("~/User_Data/asset.png")))
            {
                Image imageData = ResizeImage(image, 120, 120, image.Width, image.Height);
                string base64String = this.ImageToBase64String(imageData, ImageFormat.Png);
                <snip>
            }

public string ImageToBase64String(Image imageData, ImageFormat format)
    {
        using (var stream = new MemoryStream())
        {
            imageData.Save(stream, format);
            return Convert.ToBase64String(stream.ToArray());
        }
    }

    public Image ResizeImage(Image image, int canvasWidth, int canvasHeight, int originalWidth, int originalHeight)
    {
        using (Image image2 = new Bitmap(canvasWidth, canvasHeight))
        using (Graphics graphics = Graphics.FromImage(image2))
        {
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            double num = ((double)canvasWidth) / ((double)originalWidth);
            double num2 = ((double)canvasHeight) / ((double)originalHeight);
            double num3 = (num < num2) ? num : num2;
            int height = Convert.ToInt32((double)(originalHeight * num3));
            int width = Convert.ToInt32((double)(originalWidth * num3));
            int x = Convert.ToInt32((double)((canvasWidth - (originalWidth * num3)) / 2.0));
            int y = Convert.ToInt32((double)((canvasHeight - (originalHeight * num3)) / 2.0));
            graphics.Clear(Color.White);
            graphics.DrawImage(image, x, y, width, height);
            ImageCodecInfo.GetImageEncoders();
            using (var parameters = new EncoderParameters(1))
            {
                parameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
            }
            return image2;
        }
    }

这是我的调试器的屏幕截图...这是在imageData建立后立即停止,并且在调用ImageToBase64String之前停止。 imageData中的这些异常不会使应用程序崩溃,但肯定看起来不正确吗? enter image description here

1 个答案:

答案 0 :(得分:2)

简短的回答是您通过image2块处理using,然后尝试在方法之外使用它。如果你检查ImageData,你会看到各种不良数据和例外:

enter image description here

如果要归还它,请不要处理它;调用代码将负责处理,如果完成它:

//using (Image image2 = new Bitmap(canvasWidth, canvasHeight))
Image image2 = new Bitmap(canvasWidth, canvasHeight);
using (Graphics graphics = Graphics.FromImage(image2))
{
    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    ...
}
return image2;

有一种更简单的方法来缩放图像,并且编解码器/质量参数代码什么都不做。

public Image ResizeImage2(Image image, int canvasWidth, int canvasHeight)
{
    // org size is already available
    Size orginalSize = image.Size;
    Size newSize = Size.Empty;
    float scale;

    if (canvasWidth != 0)
    {
        scale = (float)orginalSize.Height / orginalSize.Width;
        newSize = new Size(canvasWidth, Convert.ToInt32(scale * canvasWidth));
    }
    else if (canvasHeight != 0)
    {
        scale = (float)orginalSize.Width / orginalSize.Height;
        newSize = new Size(Convert.ToInt32(scale * canvasHeight), canvasHeight);
    }     

    //using (Image image2 = new Bitmap(canvasWidth, canvasHeight))
    Image image2 = new Bitmap(newSize.Width, newSize.Height);
    using (Graphics graphics = Graphics.FromImage(image2))
    {
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
        graphics.CompositingQuality = CompositingQuality.HighQuality;

        graphics.Clear(Color.White);
        graphics.DrawImage(image, 0, 0, newSize.Width, newSize.Height);

        return image2;
    }
}

这会根据目标宽度或高度缩放传递的图像,并减少一些变量。删除了编解码器的内容,因为您将使用Save方法:

using (Image img = Image.FromFile(@"C:\Temp\BigHead.jpg"))
{
    // resize img to the height of a PicBox
    Image imageData = ResizeImage2(img, 0, pb2.Height);
    // winforms show img
    pb2.Image = imageData;

    // get codec
    ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders()
        .FirstOrDefault(z => z.MimeType == "image/jpeg");
    using (var qparam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L))
    {
        EncoderParameters encParams = new EncoderParameters(1);
        encParams.Param[0] = qparam;
        imageData.Save(@"C:\Temp\BigHead_thumb.jpg", codec, encParams);

        // test: no encoder
        imageData.Save(@"C:\Temp\BigHead_thumb2.jpg");
    }
    // ToDo: dispose of returned image
}

调用代码可以查看图像并决定是缩放到高度还是宽度。如果要指定非默认质量级别,Image.Save方法将使用编码器。

生成的文件大小反映了编码器的影响:默认方法为72k,使用质量参数为194k。