图片压缩

实现一(只改变图片质量,不改变图片尺寸):

        /// <summary>
        /// 图片压缩(降低质量以减小文件的大小),不用保存到某个路径
        /// </summary>
        /// <param name="srcBitmap">传入的Bitmap对象</param>
        /// <param name="destStream">压缩后的Stream对象</param>
        /// <param name="level">压缩等级,0到100,0 最差质量,100 最佳</param>
        public static void Compress(Bitmap srcBitmap, Stream destStream, long level)
        {
            ImageCodecInfo myImageCodecInfo;
            Encoder myEncoder;
            EncoderParameter myEncoderParameter;
            EncoderParameters myEncoderParameters;

            myImageCodecInfo = GetEncoderInfo("image/jpeg");        //得到一个表示JPEG编码的 imagecodecinfo 对象image/jpeg
            myEncoder = Encoder.Quality;        //根据质量参数类别的全局唯一标识符创建并初始化一个编码器对象

            //创建encoderparameters对象。
            //encoderparameters 对象包含一个encoderparameter对象数组。在本例中,数组中只有一个encoderparameter对象。
            myEncoderParameters = new EncoderParameters(1);

            // Save the bitmap as a JPEG file with 给定的 quality level
            myEncoderParameter = new EncoderParameter(myEncoder, level);
            myEncoderParameters.Param[0] = myEncoderParameter;
            srcBitmap.Save(destStream, myImageCodecInfo, myEncoderParameters);
        }

        /// <summary>
        /// 图片压缩(降低质量以减小文件的大小),保存在某个路径
        /// </summary>
        /// <param name="srcBitMap">传入的Bitmap对象</param>
        /// <param name="destFile">压缩后的图片保存路径</param>
        /// <param name="level">压缩等级,0到100,0 最差质量,100 最佳</param>
        public static void Compress(Bitmap srcBitMap, string destFile, long level)
        {
            Stream s = new FileStream(destFile, FileMode.Create);
            Compress(srcBitMap, s, level);
            s.Close();
        }

        /// <summary>
        /// 获取图片编码类型信息:返回 ImageCodecInfo 的 GetEncoderInfo 方法
        /// </summary>
        /// <param name="mimeType">编码类型</param>
        /// <returns></returns>
        private static ImageCodecInfo GetEncoderInfo(String mimeType)
        {
            ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();

            foreach (ImageCodecInfo ici in encoders)
            {
                if (ici.MimeType.Equals(mimeType))
                    return ici;
            }

            return null;
        }

实现二(只改变图片质量,不改变图片尺寸):

        /// <summary>  
        /// 压缩图片  
        /// </summary>  
        /// <param name="filePath">要压缩的图片的路径</param>  
        /// <param name="filePath_ystp">压缩后的图片的路径</param>  
        public void ystp(string filePath, string filePath_ystp)
        {
            Bitmap bmp = null;              //Bitmap
            ImageCodecInfo ici = null;      //ImageCoderInfo
            Encoder ecd = null;             //Encoder
            EncoderParameter ept = null;    //EncoderParameter
            EncoderParameters eptS = null;  //EncoderParameters

            try
            {
                bmp = new Bitmap(filePath);
                ici = this.getImageCoderInfo("image/jpeg");     //图片编码信息
                ecd = Encoder.Quality;              //根据质量参数类别的全局唯一标识符创建并初始化一个编码器对象
                eptS = new EncoderParameters(1);
                ept = new EncoderParameter(ecd, 10L);
                eptS.Param[0] = ept;
                bmp.Save(filePath_ystp, ici, eptS);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                bmp.Dispose();

                ept.Dispose();

                eptS.Dispose();
            }
        }

        /// <summary>  
        /// 获取图片编码类型信息  
        /// </summary>  
        /// <param name="coderType">编码类型</param>  
        /// <returns>ImageCodecInfo</returns>  
        private ImageCodecInfo getImageCoderInfo(string coderType)
        {
            ImageCodecInfo[] iciS = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo retIci = null;

            foreach (ImageCodecInfo ici in iciS)
            {
                if (ici.MimeType.Equals(coderType))
                    retIci = ici;
            }

            return retIci;
        }

实现三(可同时实现质量压缩和尺寸按倍数收缩):

        #region getThumImage  
        /**/  
        /// <summary>  
        /// 生成缩略图  
        /// </summary>  
        /// <param name="sourceFile">原始图片文件</param>  
        /// <param name="quality">质量压缩比</param>  
        /// <param name="multiple">收缩倍数</param>  
        /// <param name="outputFile">输出文件名</param>  
        /// <returns>成功返回true,失败则返回false</returns>  
        public static bool getThumImage(String sourceFile, long quality, int multiple, String outputFile)  
        {  
            try  
            {  
                long imageQuality = quality;  
                Bitmap sourceImage = new Bitmap(sourceFile);  
                ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");  
                System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;  
                EncoderParameters myEncoderParameters = new EncoderParameters(1);  
                EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, imageQuality);  
                myEncoderParameters.Param[0] = myEncoderParameter;  
                float xWidth = sourceImage.Width;  
                float yWidth = sourceImage.Height;  
                Bitmap newImage = new Bitmap((int)(xWidth / multiple), (int)(yWidth / multiple));  
                Graphics g = Graphics.FromImage(newImage);  
  
                g.DrawImage(sourceImage, 0, 0, xWidth / multiple, yWidth / multiple);  
                g.Dispose();  
                newImage.Save(outputFile, myImageCodecInfo, myEncoderParameters);  
                return true;  
            }  
            catch  
            {  
                return false;  
            }  
        }  
        #endregion getThumImage  
  
        /**/  
        /// <summary>  
        /// 获取图片编码信息  
        /// </summary>  
        private static ImageCodecInfo GetEncoderInfo(String mimeType)  
        {  
            int j;  
            ImageCodecInfo[] encoders;  
            encoders = ImageCodecInfo.GetImageEncoders();  
            for (j = 0; j < encoders.Length; ++j)  
            {  
                if (encoders[j].MimeType == mimeType)  
                    return encoders[j];  
            }  
            return null;  
        }

实现四(可按指定尺寸进行压缩):

       /// <summary>
        /// 压缩图片
        /// </summary>
        /// <returns></returns>
        public string ResizePic()
        {
            #region 压缩图片开始
            bool IsImgFile = true;  //判断是否为图片文件
            string filePathName = "123";   //文件存储的路径(文件夹名称)
            string fileName = "a.jpg";   //上传文件的原始名称
            string fileSysName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + fileName;  //修改后的文件名称
            string filePath = "";   //文件路径
            string strImgPath = "/fileupload/";   //上传路径
            if (IsImgFile)
            {
                int maxWidth = 600;   //图片宽度最大限制
                int maxHeight = 400;  //图片高度最大限制
                System.Drawing.Image imgPhoto =
                    System.Drawing.Image.FromFile(Server.MapPath(strImgPath) + filePathName + "/" + fileSysName);
                int imgWidth = imgPhoto.Width;
                int imgHeight = imgPhoto.Height;
                if (imgWidth > imgHeight)  //如果宽度超过高度以宽度为准来压缩
                {
                    if (imgWidth > maxWidth)  //如果图片宽度超过限制
                    {
                        float toImgWidth = maxWidth;   //图片压缩后的宽度
                        float toImgHeight = imgHeight / (float)(imgWidth / toImgWidth); //图片压缩后的高度

                        System.Drawing.Bitmap img = new System.Drawing.Bitmap(imgPhoto,
                                                                              int.Parse(toImgWidth.ToString()),
                                                                              int.Parse(toImgHeight.ToString()));
                        string strResizePicName = Server.MapPath(strImgPath) + filePathName + "/_small_" + fileSysName;
                        img.Save(strResizePicName);  //保存压缩后的图片
                        filePath = strImgPath + filePathName + "/_small_" + fileSysName;  //返回压缩后的图片路径
                    }
                }
                else
                {
                    if (imgHeight > maxHeight)
                    {
                        float toImgHeight1 = maxHeight;
                        float toImgWidth1 = imgWidth / (float)(imgHeight / toImgHeight1);

                        System.Drawing.Bitmap img = new System.Drawing.Bitmap(imgPhoto,
                                                                              int.Parse(toImgWidth1.ToString()),
                                                                              int.Parse(toImgHeight1.ToString()));
                        string strResizePicName = Server.MapPath(strImgPath) + filePathName + "/_small_" + fileSysName;
                        img.Save(strResizePicName);
                        filePath = strImgPath + filePathName + "/_small_" + fileSysName;
                    }
                }
            }
            return filePath;
            #endregion
        }

实现五(高质量压缩图):

  第一步为画布描绘时的质量设置,第二步为保存图片时JPEG压缩的设置。

        private Size NewSize(int maxWidth, int maxHeight, int width, int height)
        {
            double w = 0.0;
            double h = 0.0;
            double sw = Convert.ToDouble(width);
            double sh = Convert.ToDouble(height);
            double mw = Convert.ToDouble(maxWidth);
            double mh = Convert.ToDouble(maxHeight);

            if ( sw < mw && sh < mh )
            {
                w = sw;
                h = sh;
            }
            else if ( (sw/sh) > (mw/mh) )
            {
                w = maxWidth;
                h = (w * sh)/sw;
            }
            else
            {
                h = maxHeight;
                w = (h * sw)/sh;
            }

            return new Size(Convert.ToInt32(w), Convert.ToInt32(h));
        }

        private void SendSmallImage(string fileName, int maxWidth, int maxHeight)
        {
            System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath(fileName));
            System.Drawing.Imaging.ImageFormat thisFormat = img.RawFormat;

            Size newSize = NewSize(maxWidth, maxHeight, img.Width, img.Height);
            Bitmap outBmp = new Bitmap(newSize.Width, newSize.Height);
            Graphics g = Graphics.FromImage(outBmp);

            // 设置画布的描绘质量
            g.CompositingQuality = CompositingQuality.HighQuality; 
            g.SmoothingMode = SmoothingMode.HighQuality; 
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            g.DrawImage(img, new Rectangle(0, 0, newSize.Width, newSize.Height),
                0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
            g.Dispose();

            if (thisFormat.Equals(ImageFormat.Gif))
            {
                Response.ContentType = "image/gif";
            }
            else
            {
                Response.ContentType = "image/jpeg";
            }

            // 以下代码为保存图片时,设置压缩质量
            EncoderParameters encoderParams = new EncoderParameters();
            long[] quality = new long[1];
            quality[0] = 100;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            encoderParams.Param[0] = encoderParam;

            //获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。
            ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo jpegICI = null;
            for (int x = 0; x < arrayICI.Length; x++)
            {
                if (arrayICI[x].FormatDescription.Equals("JPEG"))
                {
                    jpegICI = arrayICI[x];//设置JPEG编码
                    break;
                }
            }

            if (jpegICI != null)
            {
                outBmp.Save(Response.OutputStream, jpegICI, encoderParams);
            }
            else
            {
                outBmp.Save(Response.OutputStream, thisFormat);
            }
            
            img.Dispose();
            outBmp.Dispose();
        }

实现六(无损高质量压缩图片):

/// 无损压缩图片    
/// <param name="sFile">原图片</param>    
/// <param name="dFile">压缩后保存位置</param>    
/// <param name="dHeight">高度</param>    
/// <param name="dWidth"></param>    
/// <param name="flag">压缩质量(数字越小压缩率越高) 1-100</param>    
/// <returns></returns>    
  
public static bool GetPicThumbnail(string sFile, string dFile, int dHeight, int dWidth, int flag)  
{  
    System.Drawing.Image iSource = System.Drawing.Image.FromFile(sFile);  
    ImageFormat tFormat = iSource.RawFormat;  
    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 = CompositingQuality.HighQuality;  
    g.SmoothingMode = SmoothingMode.HighQuality;  
    g.InterpolationMode = 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是压缩后的新路径    
        }  
        else  
        {  
            ob.Save(dFile, tFormat);  
        }  
        return true;  
    }  
    catch  
    {  
        return false;  
    }  
    finally  
    {  
        iSource.Dispose();  
        ob.Dispose();  
    }  
}  

实现七(由java代码该编,还没改完):

        //1、质量压缩方法
        private Bitmap compressImage(Bitmap image)
        {
            MemoryStream stream = new MemoryStream();
            image.Save(stream, ImageFormat.Jpeg);       //将图片以某种格式保存到流中
            Compress(image, stream, 100);               //质量压缩,这里100表示不压缩,把压缩后的数据存放到 stream 中

            int options = 100;
            while (stream.ToArray().Length / 1024 > 100)
            {
                //循环判断如果压缩后图片是否大于100kb,大于继续压缩 
                stream.//重置stream即清空stream
                image.compress(Bitmap.CompressFormat.JPEG, options, stream);//这里压缩options%,把压缩后的数据存放到stream中
                options -= 10;//每次都减少10
            }
            ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
            Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
            return bitmap;
        }

        //2、按比例压缩方法,先图片大小再图片质量压缩(根据路径获取图片并压缩)
        private Bitmap getimage(String srcPath)
        {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            //开始读入图片,此时把options.inJustDecodeBounds 设回true了
            newOpts.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空

            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
            float hh = 800f;//这里设置高度为800f
            float ww = 480f;//这里设置宽度为480f
                            //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
            int be = 1;//be=1表示不缩放
            if (w > h && w > ww)
            {//如果宽度大的话根据宽度固定大小缩放
                be = (int)(newOpts.outWidth / ww);
            }
            else if (w < h && h > hh)
            {//如果高度高的话根据宽度固定大小缩放
                be = (int)(newOpts.outHeight / hh);
            }
            if (be <= 0)
                be = 1;
            newOpts.inSampleSize = be;//设置缩放比例
                                      //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
        }
        //3、按比例压缩方法,先图片大小再图片质量压缩(根据路径获取图片并压缩)
        private Bitmap comp(Bitmap image)
        {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            if (baos.toByteArray().length / 1024 > 1024)
            {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出

                baos.reset();//重置baos即清空baos
                image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中
            }
            ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            //开始读入图片,此时把options.inJustDecodeBounds 设回true了
            newOpts.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
            float hh = 800f;//这里设置高度为800f
            float ww = 480f;//这里设置宽度为480f
                            //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
            int be = 1;//be=1表示不缩放
            if (w > h && w > ww)
            {//如果宽度大的话根据宽度固定大小缩放
                be = (int)(newOpts.outWidth / ww);
            }
            else if (w < h && h > hh)
            {//如果高度高的话根据宽度固定大小缩放
                be = (int)(newOpts.outHeight / hh);
            }
            if (be <= 0)
                be = 1;
            newOpts.inSampleSize = be;//设置缩放比例
                                      //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
            isBm = new ByteArrayInputStream(baos.toByteArray());
            bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
            return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
        }
原文地址:https://www.cnblogs.com/zhangchaoran/p/7697874.html