当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现图片压缩示例代码

Android实现图片压缩示例代码

2019年07月24日  | 移动技术网IT编程  | 我要评论

核心思想是通过bitmapfactory.options来缩放图片,主要是用到了它的insamplesize参数(采样率)

当insamplesize为1的时候,采样后的图片大小为图片的原始大小;

当insamplesize为2的时候,采样后的图片的宽和高是原来的1/2,也就是说,它的像素点是原来的1/4,占的内存自然就是原来的1/4了。以此类推。

当insamplesize小于1的时候,效果和等于1的时候是一样的。

压缩流程如下:

1.bitmapfactory.options 的injustdecodebounds参数设置为true(这个时候bitmapfactory只是解析图片的原始宽高,并不会去加载图片)。

2.从bitmapfactory.options 中取出图片的原始宽高,outwidth,outheight。

3.根据自己的需要设置合适的采样率。

4.bitmapfactory.options 的injustdecodebounds参数设置为false,然后就可以加载图片了。

下面我们看代码:

public bitmap decodesampledbitmapfrombytes(byte[] bytes,int reqwidth,int reqheight){
    final bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decodebytearray(bytes,0,bytes.length,options);
    options.insamplesize = calculateinsamplesize(options,reqwidth,reqheight);
    options.injustdecodebounds = false;
    return bitmapfactory.decodebytearray(bytes,0,bytes.length,options);
  }


public int calculateinsamplesize(bitmapfactory.options options,int reqwidth,int reqheight){
    if(reqwidth == 0 || reqheight == 0){
      return 1;
    }
    final int width = options.outwidth;
    final int height = options.outheight;
    int insamplesize = 1;
    if( width > reqwidth || height > reqheight){
      final int halfwidth = width / 2;
      final int halfheight = height / 2;
      while ((halfwidth / insamplesize) >= reqwidth && (halfheight / insamplesize) >= reqheight){
        insamplesize *=2;
      }
    }
    return insamplesize;
  }

如此一来,就完成了一张图片的压缩。另外,bitmapfactory还有其它的decode方法,我们也可以仿照上面的来写。

public bitmap decodesampledbitmapfromresource(resources res,int resid,int reqwidth,int reqheight){
    final bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decoderesource(res,resid,options);
    options.insamplesize = calculateinsamplesize(options,reqwidth,reqheight);
    options.injustdecodebounds = false;
    return bitmapfactory.decoderesource(res,resid,options);
  }
public bitmap decodesampledbitmapfromdescrptor(filedescriptor fd,int reqwidth,int reqheight){
    final bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decodefiledescriptor(fd,null,options);
    options.insamplesize = calculateinsamplesize(options,reqwidth,reqheight);
    options.injustdecodebounds = false;
    return bitmapfactory.decodefiledescriptor(fd,null,options);
  }

接下来结合一个小demo来实现一个完整的流程

先把图片压缩类封装起来

public class imageresizer {
  private static final string tag = "imageresizer";

  public imageresizer(){}

  public bitmap decodesampledbitmapfromresource(resources res,int resid,int reqwidth,int reqheight){
    final bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decoderesource(res,resid,options);
    options.insamplesize = calculateinsamplesize(options,reqwidth,reqheight);
    options.injustdecodebounds = false;
    return bitmapfactory.decoderesource(res,resid,options);
  }

  public bitmap decodesampledbitmapfrombytes(byte[] bytes,int reqwidth,int reqheight){
    final bitmapfactory.options options = new bitmapfactory.options();
    bitmap a = bitmapfactory.decodebytearray(bytes,0,bytes.length,options);
    log.d(tag, "before bitmap : " + a.getrowbytes() * a.getheight());
    options.injustdecodebounds = true;
    bitmapfactory.decodebytearray(bytes,0,bytes.length,options);
    options.insamplesize = calculateinsamplesize(options,reqwidth,reqheight);
    options.injustdecodebounds = false;
    bitmap b = bitmapfactory.decodebytearray(bytes,0,bytes.length,options);
    log.d(tag, "after bitmap : " + b.getrowbytes() * b.getheight());
    return b;
  }

  public bitmap decodesampledbitmapfromdescrptor(filedescriptor fd,int reqwidth,int reqheight){
    final bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decodefiledescriptor(fd,null,options);
    options.insamplesize = calculateinsamplesize(options,reqwidth,reqheight);
    options.injustdecodebounds = false;
    return bitmapfactory.decodefiledescriptor(fd,null,options);
  }

  public int calculateinsamplesize(bitmapfactory.options options,int reqwidth,int reqheight){
    if(reqwidth == 0 || reqheight == 0){
      return 1;
    }
    final int width = options.outwidth;
    final int height = options.outheight;
    int insamplesize = 1;
    if( width > reqwidth || height > reqheight){
      final int halfwidth = width / 2;
      final int halfheight = height / 2;
      while ((halfwidth / insamplesize) >= reqwidth && (halfheight / insamplesize) >= reqheight){
        insamplesize *=2;
      }
    }
    return insamplesize;
  }
}

然后就可以拿来用了:

activity_main2.xml

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/activity_main2"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingbottom="@dimen/activity_vertical_margin"
  android:paddingleft="@dimen/activity_horizontal_margin"
  android:paddingright="@dimen/activity_horizontal_margin"
  android:paddingtop="@dimen/activity_vertical_margin"
  tools:context="com.example.yuan.test.main2activity">

  <imageview
    android:id="@+id/main2iv"
    android:layout_width="200dp"
    android:layout_height="200dp" />

</relativelayout>

main2activity.java

public class main2activity extends appcompatactivity {

  private imageview iv;

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main2);
    initview();
    testhttp(iv);
  }

  private void testhttp(final imageview iv) {

    new thread(new runnable() {
      @override
      public void run() {
        string urlstring = "https://static.pexels.com/photos/295818/pexels-photo-295818.jpeg";
        httpurlconnection urlconnection = null;
        inputstream in = null;
        bytearrayoutputstream outstream = null;
        try {
          url url = new url(urlstring);
          urlconnection = (httpurlconnection) url.openconnection();
          in = urlconnection.getinputstream();
          byte[] buffer = new byte[1024];
          int len;
          outstream = new bytearrayoutputstream();
          while ((len = in.read(buffer)) != -1){
            outstream.write(buffer,0,len);
          }
          final byte[] data = outstream.tobytearray();
          runonuithread(new runnable() {
            @override
            public void run() { //在主线程加载ui
              iv.setimagebitmap(new imageresizer().decodesampledbitmapfrombytes(data,200,200));
            }
          });
        } catch (ioexception e) {
          e.printstacktrace();
        }finally {
          try {
            if(urlconnection !=null){
              urlconnection.disconnect();
            }
            if(in != null){
              in.close();
            }
            if(outstream != null){
              outstream.close();
            }
          } catch (ioexception e) {
            e.printstacktrace();
          }
        }
      }
    }).start();
  }

  private void initview() {
    iv = (imageview) findviewbyid(r.id.main2iv);
  }
}

最后记得获取网络权限

运行的结果:

压缩前后的bitmap大小对比

压缩前后的bitmap大小对比

压缩前后的bitmap大小对比

这里写图片描述 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网