精华内容
下载资源
问答
  • Luban(鲁班)微信朋友圈的图片压缩算法 mage compression with efficiency very close to WeChat Moments
  • Python version of Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法
  • 文中的即时通讯应用系统基于中小型APP中即时聊天功能的实现,为了提高轻量级聊天功能的性能,特别需要解决聊天中图片压缩的问题,在保证客户端图片压缩质量的同时可以在一定程度上降低服务器端负载,让图片数据可以...
  • android经典图片压缩算法 永不失真

    千次下载 热门讨论 2013-12-19 10:21:56
    对各种大图片进行压缩,压缩不失真。大图片压缩后大小在100k以内,可以根据自己的需求进行设置压缩大小。
  • 图片压缩算法

    2017-09-25 15:15:02
    android士大夫撒啊摔 阿斯顿发生水淀粉阿斯顿发阿斯顿发生暗示法sad 发生的奥迪发生的发送短发 阿斯顿发安抚阿斯顿发
  • 想到App巨头“微信”会是怎么处理,Luban(鲁班)就是通过在微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。 因为有其他语言也想要实现Luban,所以描述了一遍算法步骤。...
  • 随着手机拍照分辨率的提升,图片的压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经... 此处通过python实现的鲁班压缩图片方法是最接近微信的一种压缩算法,方法实现简洁,不需要特殊库处理,可直接进行调用。
  • android 图片压缩算法-luban

    千次阅读 2018-02-27 19:35:54
    图片压缩算法-luban luban 鲁班算法是号称最接近微信朋友圈图片压缩算法的一种图片压缩算法,GitHub 地址: https://github.com/Curzibn/Luban 根据作者提供的数据,压缩效果如下: 内容 原图 Luban ...

    图片压缩算法-luban

    luban 鲁班算法是号称最接近微信朋友圈图片压缩算法的一种图片压缩算法,GitHub 地址:

    https://github.com/Curzibn/Luban

    根据作者提供的数据,压缩效果如下:

    内容原图LubanWechat
    截屏 720P720*1280,390k720*1280,87k720*1280,56k
    截屏 1080P1080*1920,2.21M1080*1920,104k1080*1920,112k
    拍照 13M(4:3)3096*4128,3.12M1548*2064,141k1548*2064,147k
    拍照 9.6M(16:9)4128*2322,4.64M1032*581,97k1032*581,74k
    滚动截屏1080*6433,1.56M1080*6433,351k1080*6433,482k

    压缩原理

    这里的压缩,指的是,不影响分辨率的情况下,对图片进行压缩,那么图片压缩的原理是什么呢?假设一张原始,例如小米五相机拍摄的图片,分辨率是 3456 X 4608 px,每个像素使用 32位表示,那么所占内存如下:

    3456 X 4608 X 4 = 63700992 字节 =60.75 MB,然而实际上,却不是,我们看到的原图大小,可能是5 MB 左右,那么实际上, jpg 格式采用了特殊的编码格式,所以实际上,我们可以对 jpg 格式进行多次压缩,根据维基百科资料显示,在原始 jpg 图片压缩为 六分一的 质量之后,人眼是无法察觉有损失 差距的

    压缩操作代码实现分析

    压缩一个图片的代码如下:

    Luban.with(this)
        .load(photos)//设置压缩图片文件路径,全路径
        .ignoreBy(100)//设置忽略压缩的大小上限
        .setTargetDir(getPath())//设置压缩输出文件目录
        .setCompressListener(new OnCompressListener() {
          @Override
          public void onStart() {
          }
    
          @Override
          public void onSuccess(File file) {
            showResult(photos, file);
          }
    
          @Override
          public void onError(Throwable e) {
          }
        }).launch();

    主要看 launch() 方法,如下:

    @UiThread private void launch(final Context context) {
        //检查路径准确性以及是否设置了回调监听器
      if (mPaths == null || mPaths.size() == 0 && mCompressListener != null) {
        mCompressListener.onError(new NullPointerException("image file cannot be null"));
      }
    
      Iterator<String> iterator = mPaths.iterator();
      while (iterator.hasNext()) {
        final String path = iterator.next();
        if (Checker.isImage(path)) {
            // 使用单线程池执行器,一次只能执行一个线程
          AsyncTask.SERIAL_EXECUTOR.execute(new Runnable() {
            @Override public void run() {
              try {
                mHandler.sendMessage(mHandler.obtainMessage(MSG_COMPRESS_START));//发送开始压缩的信息
                //开始压缩,实际起压缩作用的是 Engine 类的 compress() 方法
                File result = Checker.isNeedCompress(mLeastCompressSize, path) ?
                    new Engine(path, getImageCacheFile(context, Checker.checkSuffix(path))).compress() :
                    new File(path);
    
                mHandler.sendMessage(mHandler.obtainMessage(MSG_COMPRESS_SUCCESS, result));
              } catch (IOException e) {
                mHandler.sendMessage(mHandler.obtainMessage(MSG_COMPRESS_ERROR, e));
              }
            }
          });
        } else {
          mCompressListener.onError(new IllegalArgumentException("can not read the path : " + path));
        }
        iterator.remove();
      }
    }

    然后这里实际起作用的是 Engine 的 compress() 方法,首先会创建一个新的 Engine() 对象,调用方法如下:

    Engine(String srcImg, File tagImg) throws IOException {
      if (Checker.isJPG(srcImg)) {//判断格式是否 jpg 或者 jpeg
        this.srcExif = new ExifInterface(srcImg);//创建 ExifInterface 对象,这个对象用于图片读取,旋转,生成缩略图
      }
      this.tagImg = tagImg;
      this.srcImg = srcImg;
    
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;//设置读取方法为只读取边界大小
      options.inSampleSize = 1;
    
      BitmapFactory.decodeFile(srcImg, options);
      this.srcWidth = options.outWidth;//设置为图片原始宽高
      this.srcHeight = options.outHeight;
    }

    Engine 类里面的值都是通过 Luban.Builder 传递过来的。

    具体的压缩比例计算,在 computeSize() 方法里面,computeSize() 方法主要是根据图片的宽高比,对图片进行压缩,这个方法的返回值,设置的是

    private int computeSize() {
        //将 srcWidth 和 srcHeight 设置为偶数,方便除法计算
      srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
      srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;
    
      int longSide = Math.max(srcWidth, srcHeight);
      int shortSide = Math.min(srcWidth, srcHeight);
    
      float scale = ((float) shortSide / longSide);
      if (scale <= 1 && scale > 0.5625) {
        if (longSide < 1664) {
          return 1;
        } else if (longSide >= 1664 && longSide < 4990) {
          return 2;
        } else if (longSide > 4990 && longSide < 10240) {
          return 4;
        } else {
          return longSide / 1280 == 0 ? 1 : longSide / 1280;
        }
      } else if (scale <= 0.5625 && scale > 0.5) {
        return longSide / 1280 == 0 ? 1 : longSide / 1280;
      } else {
        return (int) Math.ceil(longSide / (1280.0 / scale));
      }
    }
    1. 判断图片比例值,是否处于以下区间内;

      • [1, 0.5625) 即图片处于 [1:1 ~ 9:16) 比例范围内
      • [0.5625, 0.5) 即图片处于 [9:16 ~ 1:2) 比例范围内
      • [0.5, 0) 即图片处于 [1:2 ~ 1:∞) 比例范围内
    2. 判断图片最长边是否过边界值;

      • [1, 0.5625) 边界值为:1664 * n(n=1), 4990 * n(n=2), 1280 * pow(2, n-1)(n≥3)
      • [0.5625, 0.5) 边界值为:1280 * pow(2, n-1)(n≥1)
      • [0.5, 0) 边界值为:1280 * pow(2, n-1)(n≥1)
    3. 计算压缩图片实际边长值,以第2步计算结果为准,超过某个边界值则:width / pow(2, n-1),height/pow(2, n-1)

    4. 计算压缩图片的实际文件大小,以第2、3步结果为准,图片比例越大则文件越大。

    size = (newW * newH) / (width * height) * m;

    • [1, 0.5625) 则 width & height 对应 1664,4990,1280 * n(n≥3),m 对应 150,300,300;
    • [0.5625, 0.5) 则 width = 1440,height = 2560, m = 200;
    • [0.5, 0) 则 width = 1280,height = 1280 / scale,m = 500;注:scale为比例值

      1. 判断第4步的size是否过小
    • [1, 0.5625) 则最小 size 对应 60,60,100

    • [0.5625, 0.5) 则最小 size 都为 100
    • [0.5, 0) 则最小 size 都为 100

      1. 将前面求到的值压缩图片 width, height, size 传入压缩流程,压缩图片直到满足以上数值

    那么为什么会采用这种压缩方式呢?

    我们很简单的可以理解,移动设备的分辨率有限,我们只需要保证,能够压缩的图片能够在主流分辨率上能够达到合适的显示效果,并且最大可能的去压缩图片分辨率,这就是图片压缩的初衷。所以,合理之处便是在于设置这个分辨率了,luban 算法就是起了这个效果吧。

    最终执行压缩操作的方法 cmopress() 方法

    File compress() throws IOException {
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inSampleSize = computeSize();//根据图片比例,设置压缩比例
    
      Bitmap tagBitmap = BitmapFactory.decodeFile(srcImg, options);//压缩图片
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
    
      tagBitmap = rotatingImage(tagBitmap);
      tagBitmap.compress(Bitmap.CompressFormat.JPEG, 60, stream);
      tagBitmap.recycle();//将 bitmap 写入到输入流
    
      FileOutputStream fos = new FileOutputStream(tagImg);//将输入流写入文件
      fos.write(stream.toByteArray());
      fos.flush();
      fos.close();
      stream.close();
    
      return tagImg;
    }

    这里比较简单,就不多阐述了。

    展开全文
  • 微信朋友圈图片压缩算法

    千次阅读 2019-10-25 11:48:08
    转自: 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ... 描述 图片作为App中重要的一个元素,非常具有表现力,图片...所以开发者要对图片进行裁切和质量压缩。但是...

    转自:

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/u014220518/article/details/58136932


    描述
    图片作为App中重要的一个元素,非常具有表现力,图片既要让用户能看清楚,又能让发布图片的用户能快速的上传。所以开发者要对图片进行裁切和质量压缩。但是裁切尺寸质量压缩比设置成多少却很难控制好,如果设置不当会导致图片显示效果很差。

    微信是一个很好的参照物,被大家广为使用并接受。这个扩展就是通过发送微信朋友圈和聊天会话发送了大量图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。

    算法
    图片尺寸
    宽高均 <= 1280,图片尺寸大小保持不变
    宽或高 > 1280 && 宽高比 <= 2,取较大值等于1280,较小值等比例压缩
    宽或高 > 1280 && 宽高比 > 2 && 宽或高 < 1280,图片尺寸大小保持不变
    宽高均 > 1280 && 宽高比 > 2,取较小值等于1280,较大值等比例压缩
    注:当宽和高均小于1280,并且宽高比大于2时,微信聊天会话和微信朋友圈的处理不一样。
    朋友圈:取较小值等于1280,较大值等比例压缩
    聊天会话:取较小值等于800,较大值等比例压缩

    图片质量
    经过大量的测试,微信的图片压缩质量值 ≈ 0.5

    UIImageJPEGRepresentation(resizeImage, 0.5)

    效果对比
    original    wechat    this
    1500 * 4000, 2.5MB    800 * 2134, 325KB    800 * 2134, 306KB
    960 * 600, 210KB    960 * 600, 147KB    960 * 600, 147KB
    800 * 1280, 595KB    800 * 1280, 140KB    800 * 1280, 142KB
    1080 * 1920, 1.8MB    720 * 1280, 139KB    720 * 1280, 140KB
    640 * 1136, 505KB    640 * 1136, 68KB    640 * 1136 69KB
    4000 * 3000, 497KB    1280 * 960, 140KB    1280 * 960, 139KB
    2560 * 1600, 232KB    1280 * 800 112KB    1280 * 800, 112KB
    800 * 2138, 307KB    800 * 2134, 649KB    800 * 2138, 599KB
    3351 * 1430, 386KB    1874 * 800, 296KB    1875 * 800, 286KB
    3000 *1300, 458KB    1846 * 800 322KB    1847 * 800, 307KB
    8323 * 5793, 19.67MB    1280 * 890, 428KB    1280 * 891, 465KB


     

    展开全文
  • C#图片压缩算法

    千次阅读 2018-06-26 18:13:44
    /// 无损压缩图片 /// &lt;/summary&gt; /// &lt;param name="sFile"&gt;原图片地址&lt;/param&gt; /// &lt;param name="dFile"&gt;压缩后保存图片地址&lt...
    /// <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();
        }
    }
    
    展开全文
  • c# 图片压缩算法

    千次阅读 2016-08-05 10:00:23
    #region 图片压缩 private static byte[] CompressionImage(Stream fileStream, long quality) { using (System.Drawing.Image img = System.Drawing.Image.FromStream(fileStream))
      #region 图片压缩
            private static byte[] CompressionImage(Stream fileStream, long quality)
            {
                using (System.Drawing.Image img = System.Drawing.Image.FromStream(fileStream))
                {
                    using (Bitmap bitmap = new Bitmap(img))
                    {
                        ImageCodecInfo CodecInfo = GetEncoder(img.RawFormat);
                        System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
                        EncoderParameters myEncoderParameters = new EncoderParameters(1);
                        EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
                        myEncoderParameters.Param[0] = myEncoderParameter;
                        using (MemoryStream ms = new MemoryStream())
                        {
                            bitmap.Save(ms, CodecInfo, myEncoderParameters);
                            myEncoderParameters.Dispose();
                            myEncoderParameter.Dispose();
                            return ms.ToArray();
                        }
                    }
                }
            }
    
            private static ImageCodecInfo GetEncoder(ImageFormat format)
            {
                ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
                foreach (ImageCodecInfo codec in codecs)
                {
                    if (codec.FormatID == format.Guid)
                    { return codec; }
                }
                return null;
            }
            #endregion
    

    展开全文
  • 开源最前线(ID:OpenSourceTop) 猿妹 整编综合自:https://github.com/Curzibn/Luban目前做APP开发总绕不开图片元素,如今手机拍照分辨率都非常高,...于是,许多开发者就会想:微信是如何处理图片压缩的呢?据了...
  • android 图片压缩算法

    2017-02-22 14:20:27
    由源图像压缩为固定目标尺寸的图像。 1.求源宽,高为计算压缩尺寸做准备。 BitampFactory.Options.inSampleSize 控制BitmapFactory分配恰当的内存空间。 BitampFactory.Options.inJustDecodeBounds 为true...
  • 最接近微信的图片压缩算法Luban

    千次阅读 2016-11-09 10:32:17
    Luban是一个国内很牛逼的图片压缩库:https://github.com/Curzibn/Luban 使用这个库有很多东西都没法自己修改了(比如压缩后图片保存的地址)。所以我把源码弄下来。自己做一个util包。用起来就很方便了。 这里把...
  • 基于Luban图片压缩算法在即时聊天APP中的应用.pdf
  • Luban-android最接近微信朋友圈的图片压缩算法 目前做App开发总绕不开图片这个元素。但是随着手机拍照分辨率的提升,图片的压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经有很多文章介绍。但是裁切成多少...
  • iOS-微信朋友圈图片压缩算法

    千次阅读 2018-06-07 09:39:08
    描述图片作为App中重要的一个元素,非常具有表现力,图片既要让用户能看清楚,...这个扩展就是通过发送微信朋友圈和聊天会话发送了大量图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。算法图片尺寸宽高均...
  • 图片压缩算法,保证图片不失真

    千次阅读 2015-04-18 14:08:06
    然后,压缩图片可能会导致图片的失真等等问题,在这里,我将在工作中使用的比较好的图片压缩方法,分享给大家。 //此处的path为文件的绝对路径 public static Bitmap revitionImage(String path) throws IOException...
  • Java 压缩图片资源的算法demo,采用基本的java流操作实现!
  • 用C/C++语言实现了JPEG图像压缩算法
  • js压缩算法

    2013-01-20 22:37:59
    对静态图片压缩 js压缩算法
  • jbig银联用的图片压缩算法

    热门讨论 2014-12-15 21:47:00
    jbig银联用的图片压缩算法 ,压缩图片的好工具,工具很多,但源码不好找
  • C++ 图像压缩算法

    热门讨论 2014-03-17 22:14:28
    基于C++的图像压缩算法,可以压缩多种类型的图片,可调压缩率
  • Android之常见的图片压缩算法

    千次阅读 2016-04-18 09:28:19
    这里为大家提供一些常用的图片压缩算法,帮助大家在日常开发过程中解决图片上传时,图片压缩的问题。上一篇的博文http://blog.csdn.net/loveyaozu/article/details/51160482中其实已经为大家提供了图片的
  • Luban(鲁班)——Android图片压缩工具,仿微信朋友圈压缩策略 项目描述 目前做app开发总绕不开图片这个元素。但是随着手机拍照分辨率的提升,图片的压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经有...
  • 本文来自图鸭科技团队的投稿,他们用深度学习技术设计、优化图片压缩算法,在保证图像画质的情况下能节省55%带宽。本文将介绍实现方法及测试对比。随着互联网的发展,人们对高清图片的需求也在不断增加,在保证图像...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,613
精华内容 36,245
关键字:

图片压缩算法