c#压缩图片问题总结

代码:

方法1:方法较简单,相对于其他方法来说不安全,Size参数也不太合适,换成尺寸大小更好一点

public static Bitmap GetImageThumb(Bitmap mg, Size newSize)
        {
            double ratio = 0d;
            double myThumbWidth = 0d;
            double myThumbHeight = 0d;
            int x = 0;
            int y = 0;
            Bitmap bp;

            if ((mg.Width / Convert.ToDouble(newSize.Width)) > (mg.Height /
            Convert.ToDouble(newSize.Height)))
                ratio = Convert.ToDouble(mg.Width) / Convert.ToDouble(newSize.Width);
            else
                ratio = Convert.ToDouble(mg.Height) / Convert.ToDouble(newSize.Height);
            myThumbHeight = Math.Ceiling(mg.Height / ratio);
            myThumbWidth = Math.Ceiling(mg.Width / ratio);

            Size thumbSize = new Size((int)newSize.Width, (int)newSize.Height);
            bp = new Bitmap(newSize.Width, newSize.Height);
            x = (newSize.Width - thumbSize.Width) / 2;
            y = (newSize.Height - thumbSize.Height);
            System.Drawing.Graphics g = Graphics.FromImage(bp);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            Rectangle rect = new Rectangle(x, y, thumbSize.Width, thumbSize.Height);
            g.DrawImage(mg, rect, 0, 0, mg.Width, mg.Height, GraphicsUnit.Pixel);

            return bp;

        }

方法二:结构及使用非托管资源的处理相比第一个要好一些,但压缩后文件大小和第一个差不多

protected static Size CalculateDimensions(Size originalSize, int targetSize)
        {
            var newSize = new Size();
            if (originalSize.Height > originalSize.Width) // portrait 
            {
                newSize.Width = (int)(originalSize.Width * (float)(targetSize / (float)originalSize.Height));
                newSize.Height = targetSize;
            }
            else // landscape or square
            {
                newSize.Height = (int)(originalSize.Height * (float)(targetSize / (float)originalSize.Width));
                newSize.Width = targetSize;
            }
            return newSize;
        }
        public  static byte[] ValidatePicture(byte[] pictureBinary, string mimeType, ImageFormat rawFormat)
        {
            using (var stream1 = new MemoryStream(pictureBinary))
            {
                using (var b = new Bitmap(stream1))
                {
                    var maxSize = 720;
                    if ((b.Height <= maxSize) && (b.Width <= maxSize))
                        return pictureBinary;

                    var newSize = CalculateDimensions(b.Size, maxSize);
                    using (var newBitMap = new Bitmap(newSize.Width, newSize.Height))
                    {
                        using (var g = Graphics.FromImage(newBitMap))
                        {
                            g.SmoothingMode = SmoothingMode.HighQuality;
                            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            g.CompositingQuality = CompositingQuality.HighQuality;
                            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                            g.DrawImage(b, 0, 0, newSize.Width, newSize.Height);

                            using (var stream2 = new MemoryStream())
                            {
                                var ep = new EncoderParameters();
                                ep.Param[0] = new EncoderParameter(Encoder.Quality, 80L);
                                ImageCodecInfo ici = GetImageCodecInfoFromMimeType(mimeType);
                                if (ici == null)
                                    ici = GetImageCodecInfoFromMimeType("image/jpeg");
                                newBitMap.Save(stream2, ici, ep);
                                newBitMap.Save(@"C:\Users\Administrator\Desktop\照片\name91.jpg", ici, ep);
                                newBitMap.Save(@"C:\Users\Administrator\Desktop\照片\name9.jpg",rawFormat);
                                return stream2.GetBuffer();
                            }
                        }
                    }
                }
            }
        }
        protected static ImageCodecInfo GetImageCodecInfoFromMimeType(string mimeType)
        {
            var info = ImageCodecInfo.GetImageEncoders();
            foreach (var ici in info)
                if (ici.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase))
                    return ici;
            return null;
        }

方法三:相对于其他两个方法,这个是循环压缩的,一直到满足条件为止,同时还把文件给保存下来了

/// <summary>
        /// 无损压缩图片
        /// </summary>
        /// <param name="sFile">原图片地址</param>
        /// <param name="dFile">压缩后保存图片地址</param>
        /// <param name="flag">压缩质量(数字越小压缩率越高)1-100</param>
        /// <param name="size">压缩后图片的最大大小</param>
        /// <param name="sfsc">是否是第一次调用</param>
        /// <returns></returns>
        public static bool CompressImage(string sFile, string dFile, int flag = 90, int size = 300, bool sfsc = true)
        {
            //如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true
            FileInfo firstFileInfo = new FileInfo(sFile);
            if (sfsc == true && firstFileInfo.Length < size * 1024)
            {
                firstFileInfo.CopyTo(dFile);
                return true;
            }
            Image iSource = Image.FromFile(sFile);
            ImageFormat tFormat = iSource.RawFormat;
            int dHeight = iSource.Height / 2;
            int dWidth = iSource.Width / 2;
            int sW = 0, sH = 0;
            //按比例缩放
            Size tem_size = new Size(iSource.Width, iSource.Height);
            if (tem_size.Width > dHeight || tem_size.Width > dWidth)
            {
                if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
                {
                    sW = dWidth;
                    sH = (dWidth * tem_size.Height) / tem_size.Width;
                }
                else
                {
                    sH = dHeight;
                    sW = (tem_size.Width * dHeight) / tem_size.Height;
                }
            }
            else
            {
                sW = tem_size.Width;
                sH = tem_size.Height;
            }

            Bitmap ob = new Bitmap(dWidth, dHeight);
            Graphics g = Graphics.FromImage(ob);

            g.Clear(Color.WhiteSmoke);
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);

            g.Dispose();

            //以下代码为保存图片时,设置压缩质量
            EncoderParameters ep = new EncoderParameters();
            long[] qy = new long[1];
            qy[0] = flag;//设置压缩的比例1-100
            EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
            ep.Param[0] = eParam;

            try
            {
                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo jpegICIinfo = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICIinfo = arrayICI[x];
                        break;
                    }
                }
                if (jpegICIinfo != null)
                {
                    ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径
                    FileInfo fi = new FileInfo(dFile);
                    if (fi.Length > 1024 * size)
                    {
                        flag = flag - 10;
                        CompressImage(sFile, dFile, flag, size, false);
                    }
                }
                else
                {
                    ob.Save(dFile, tFormat);
                }
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                iSource.Dispose();
                ob.Dispose();
            }
        }

中间遇到的问题:

压缩完之后保存的时候,刚开始用这种方法newBitMap.Save(@"C:\Users\Administrator\Desktop\照片\name9.jpg"),保存的图片比原本的还大,以为没有压缩成功,后来用newBitMap.Save(@"C:\Users\Administrator\Desktop\照片\name9.jpg",rawFormat);保存后,图片变小了,第三种方法newBitMap.Save(@"C:\Users\Administrator\Desktop\照片\name91.jpg", ici, ep);图片的尺寸更小,和压缩效果一致。

最后根据实际业务情况选择合适的方法:

while (arr.Length > 10 * 1024)
                {
                    arr = ValidatePicture(arr, "jpg");
                }


public  static byte[] ValidatePicture(byte[] pictureBinary, string mimeType)
        {
            using (var stream1 = new MemoryStream(pictureBinary))
            {
                using (var b = new Bitmap(stream1))
                {
                    //var maxSize = 720;
                    //if ((b.Height <= maxSize) && (b.Width <= maxSize))
                    //    return pictureBinary;

                    //var newSize = CalculateDimensions(b.Size, maxSize);
                    int dHeight = b.Height / 2;
                    int dWidth = b.Width / 2;
                    int sW = 0, sH = 0;
                    //按比例缩放
                    Size tem_size = new Size(b.Width, b.Height);
                    if (tem_size.Width > dHeight || tem_size.Width > dWidth)
                    {
                        if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
                        {
                            sW = dWidth;
                            sH = (dWidth * tem_size.Height) / tem_size.Width;
                        }
                        else
                        {
                            sH = dHeight;
                            sW = (tem_size.Width * dHeight) / tem_size.Height;
                        }
                    }
                    else
                    {
                        sW = tem_size.Width;
                        sH = tem_size.Height;
                    }
                    var newSize = new Size(sW, sH);
                    using (var newBitMap = new Bitmap(newSize.Width, newSize.Height))
                    {
                        using (var g = Graphics.FromImage(newBitMap))
                        {
                            g.SmoothingMode = SmoothingMode.HighQuality;
                            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            g.CompositingQuality = CompositingQuality.HighQuality;
                            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                            g.DrawImage(b, 0, 0, newSize.Width, newSize.Height);

                            using (var stream2 = new MemoryStream())
                            {
                                var ep = new EncoderParameters();
                                ep.Param[0] = new EncoderParameter(Encoder.Quality, 50L);
                                ImageCodecInfo ici = GetImageCodecInfoFromMimeType(mimeType);
                                if (ici == null)
                                    ici = GetImageCodecInfoFromMimeType("image/jpeg");
                                newBitMap.Save(stream2, ici, ep);
                                newBitMap.Save(@"C:\Users\Administrator\Desktop\照片\name911.jpg", ici, ep);
                                return stream2.GetBuffer();
                            }
                        }
                    }
                }
            }
        }

附上 image和bitmap相互转换方法

Image img = this.pictureBox1.Image;
Bitmap map = new Bitmap(img);

Bitmap map = new Bitmap(img);
Image img=map;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值