我有一个MVC应用程序,用户上传图像,如果需要,我会为它们调整大小。较大的图片在调整大小时质量非常差,但不需要调整大小的图片保持良好/预期的质量
这个缩放到50KB
如何在不降低质量的情况下减小文件大小? 目前我只是调整图片大小。
这是代码:
Request.InputStream.Position = 0;
string Data = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
var Base64 = Data.Split(',')[1];
var BitmapBytes = Convert.FromBase64String(Base64);
while (BitmapBytes.Length > 51200)
{
int Schritte = SetSchritte(BitmapBytes.Length);
var format = Bmp.PixelFormat;
Bmp = ScaleImage(Bmp, Bmp.Width - Schritte, Bmp.Height - Schritte);
ImageHelper.ChangePixelFormat(Bmp, format);
BitmapBytes = ImageToByte(Bmp);
}
public static Bitmap ScaleImage(Image image, int maxWidth, int maxHeight)
{
var ratioX = (double)maxWidth / image.Width;
var ratioY = (double)maxHeight / image.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(image, new Rectangle(0, 0, newWidth, newHeight));
}
return newImage;
}
private int SetSchritte(int length)
{
if (length > 51200000)
{
return 400;
}
else if (length > 512000)
{
return 200;
}
else if (length > 102400)
{
return 50;
}
else if (length > 55000)
{
return 30;
}
else if (length > 51200 && length < 55000)
{
return 10;
}
return 500;
}
答案 0 :(得分:1)
正如Hans Passant在评论中所说:如果你想缩小你的位图,总是从原始图像开始。
您也可以尝试这种方法,在一行中完成所有减少。 唯一的问题是你总是会得到PixelFormat PixelFormat32bppARGB。
float ratio = 0.1f;
Bitmap reduced = new Bitmap(original,
(int)(original.Width * ratio),
(int)(original.Height * ratio));
编辑: 要解决像素格式问题,请添加此行。
Bitmap adjustedPixelFormat = reduced.Clone(new Rectangle(0,0,reduced.Width,reduced.Height), original.PixelFormat);
编辑:估算合适的比例:
int desiredSize = 51200;
int originalSize = OriginalBitmapBytes.Length;
double ration = Math.Sqrt((double)desiredSize/(double)originalSize);
// Do not change Image, if already small enough...
ratio = ratio >= 1 ? 1 : ratio;