参数在 Image.Save 上无效
Parameter is not valid on Image.Save
有人能看出这里有什么问题吗?我在 'imageData.Save' 行上得到了一个 "Parameter is not valid",但我怀疑 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 中的那些异常不会使应用程序崩溃,但肯定看起来不对吗?
简短的回答是您通过 using
块处理 image2
,然后尝试在方法之外使用它。如果您检查 ImageData
,您会看到各种错误数据和异常:
如果您要退货,请不要丢弃它;调用代码将在完成后负责处理它:
//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;
有一种更简单的缩放图像的方法,codec/quality 参数代码什么都不做。
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。
有人能看出这里有什么问题吗?我在 'imageData.Save' 行上得到了一个 "Parameter is not valid",但我怀疑 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 中的那些异常不会使应用程序崩溃,但肯定看起来不对吗?
简短的回答是您通过 using
块处理 image2
,然后尝试在方法之外使用它。如果您检查 ImageData
,您会看到各种错误数据和异常:
如果您要退货,请不要丢弃它;调用代码将在完成后负责处理它:
//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;
有一种更简单的缩放图像的方法,codec/quality 参数代码什么都不做。
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。