C# - 与其他图片相比,图片大小调整导致不正常的巨大质量损失

时间:2016-08-10 11:56:20

标签: c# image resize

我有一个MVC应用程序,用户上传图像,如果需要,我会为它们调整大小。较大的图片在调整大小时质量非常差,但不需要调整大小的图片保持良好/预期的质量

大图: Large picture

这个缩放到50KB

50KB

此图片只能降低BPP: Large

简化版看起来像这样: Color reduced. No rersizing

如何在不降低质量的情况下减小文件大小? 目前我只是调整图片大小。

这是代码:

                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;
        }

1 个答案:

答案 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;