图片压缩

来源:互联网 发布:js 代码高亮插件 编辑:程序博客网 时间:2024/06/16 06:39

需要依赖的

glide Rxjava retrofit


compile 'com.squareup.retrofit2:retrofit:2.2.0'compile 'com.squareup.retrofit2:converter-gson:2.2.0'compile 'io.reactivex.rxjava2:rxjava:2.1.3'compile 'io.reactivex.rxjava2:rxandroid:2.0.1'implementation project(':library-demonstrate')compile 'jp.wasabeef:glide-transformations:3.0.1'


接口

public interface NetServerInterface {    @GET    Call<ResponseBody> getBitmap(@Url String url);}


/*1,质量压缩法    1.1质量压缩不会减少图片的像素    1.2在像素不变的前提下改变图片的位深及透明度等,来达到压缩图片的目的。    1.3压缩的图片文件大小会有改变,但是导入成bitmap后占得内存是不变的2,采样率压缩法    2.1内存的使用少,不会过多的占用内存    2.2可以先只读取图片的边,通过宽和高设定好取样率后再加载图片    2.33,缩放法    3.1通过缩放图片像素来减少图片占用内存大小 */public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private static final String IMG_URL_0 = "http://pic.xiami.net/images/artistlogo/77/14677816895777.jpg";    protected TextView tvOld;    protected TextView tv3;    private String baseUrl = "http://pic.xiami.net";    private int contentLength;    private String IMG_URL_1 = "http://pic9.nipic.com/20100823/4361515_000842599423_2.jpg";    private String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/bitmaps/";    private void showList() {        DialogUtil.showListDialog(this, "Android中图片压缩方案", new String[]{                "0,加载原图",                "1,下载原图",                "2,质量压缩法,不压缩保存到本地",                "3,质量压缩法,质量压缩保存到本地",                "4,采样率压缩法,保存",                "5,缩放法,方式一!",                "6,缩放法,方式二!",        }, new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                switch (which) {                    case 0:                        //加载原图,并且展示!                        load0();                        break;                    case 1:                        //下载原图,并且保存本地,从本加载展示!                        load1();                        break;                    case 2:                        //                        load2();                        break;                    case 3:                        load3();                        break;                    case 4:                        load4();                        break;                    case 5:                        load5();                        break;                    case 6:                        load6();                        break;                }            }        });    }    private void load6() {        Observable.create(new ObservableOnSubscribe<String>() {            @Override            public void subscribe(ObservableEmitter<String> e) throws Exception {                ResponseBody body = new Retrofit.Builder()                        .baseUrl(baseUrl)                        .build()                        .create(NetServerInterface.class)                        .getBitmap(IMG_URL_1)                        .execute()                        .body();                contentLength = (int) body.contentLength() / 1024;                InputStream stream = body                        .byteStream();                Bitmap image = BitmapFactory.decodeStream(stream);                ByteArrayOutputStream out = new ByteArrayOutputStream();                image.compress(Bitmap.CompressFormat.JPEG, 85, out);                int size = contentLength;                //--原大小/内存小小后,开平方根.                float zoom = (float)Math.sqrt(size * 1024 / (float)out.toByteArray().length);//                Matrix matrix = new Matrix();                matrix.setScale(zoom, zoom);                Bitmap result = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);                //清空.                out.reset();                result.compress(Bitmap.CompressFormat.JPEG, 85, out);                while(out.toByteArray().length > size * 1024){                    DemonstrateUtil.showLogResult(out.toByteArray().length+"***");                    matrix.setScale(0.9f, 0.9f);                    result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);                    out.reset();                    result.compress(Bitmap.CompressFormat.JPEG, 85, out);                }                File file = new File(Environment.getExternalStorageDirectory(), "load6.jpg");                FileOutputStream fos = new FileOutputStream(file);                fos.write(out.toByteArray());                fos.flush();                fos.close();                String filePath = file.getPath();                e.onNext(filePath);            }        })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String path) throws Exception {                        tvOld.setText("原始大小:" + contentLength + "kb");                        File file = new File(path);                        int fileLenth = (int) (file.length() / 1024);                        tv.setText("保存后大小:" + fileLenth + "kb");                        Bitmap bitmap = BitmapFactory.decodeFile(path);                        int byteCount = bitmap.getByteCount() / 1024;                        tv3.setText("加载到内存的大小:" + byteCount);                        iv.setImageBitmap(bitmap);                    }                });    }    private void load5() {        Observable.create(new ObservableOnSubscribe<String>() {            @Override            public void subscribe(ObservableEmitter<String> e) throws Exception {                ResponseBody body = new Retrofit.Builder()                        .baseUrl(baseUrl)                        .build()                        .create(NetServerInterface.class)                        .getBitmap(IMG_URL_1)                        .execute()                        .body();                contentLength = (int) body.contentLength() / 1024;                InputStream stream = body                        .byteStream();                Bitmap bmp = BitmapFactory.decodeStream(stream);                // 尺寸压缩倍数,值越大,图片尺寸越小                int ratio = 2;                // 压缩Bitmap到对应尺寸                Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Bitmap.Config.ARGB_8888);                Canvas canvas = new Canvas(result);                Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);                canvas.drawBitmap(bmp, null, rect, null);                ByteArrayOutputStream baos = new ByteArrayOutputStream();                // 把压缩后的数据存放到baos中                result.compress(Bitmap.CompressFormat.JPEG, 100, baos);                File file = new File(Environment.getExternalStorageDirectory(), "load5.jpg");                FileOutputStream fos = new FileOutputStream(file);                fos.write(baos.toByteArray());                fos.flush();                fos.close();                String filePath = file.getPath();                e.onNext(filePath);            }        })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String path) throws Exception {                        tvOld.setText("原始大小:" + contentLength + "kb");                        File file = new File(path);                        int fileLenth = (int) (file.length() / 1024);                        tv.setText("保存后大小:" + fileLenth + "kb");                        Bitmap bitmap = BitmapFactory.decodeFile(path);                        int byteCount = bitmap.getByteCount() / 1024;                        tv3.setText("加载到内存的大小:" + byteCount);                        iv.setImageBitmap(bitmap);                    }                });    }    private void load4() {        Observable.create(new ObservableOnSubscribe<String>() {            @Override            public void subscribe(ObservableEmitter<String> e) throws Exception {                ResponseBody body = new Retrofit.Builder()                        .baseUrl(baseUrl)                        .build()                        .create(NetServerInterface.class)                        .getBitmap(IMG_URL_1)                        .execute()                        .body();                contentLength = (int) body.contentLength() / 1024;                InputStream stream = body                        .byteStream();                File file = new File(Environment.getExternalStorageDirectory(), "load4.jpg");                FileOutputStream out = new FileOutputStream(file);                out.write(body.bytes());                out.close();                String filePath = file.getPath();                e.onNext(filePath);            }        })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String path) throws Exception {                        tvOld.setText("原始大小:" + contentLength + "kb");                        File file = new File(path);                        int fileLenth = (int) (file.length() / 1024);                        tv.setText("保存后大小:" + fileLenth + "kb");                        BitmapFactory.Options newOpts = new BitmapFactory.Options();                        //开始读入图片,此时把options.inJustDecodeBounds 设回true了                        newOpts.inJustDecodeBounds = true;                        //此时返回bm为空                        Bitmap bitmap = BitmapFactory.decodeFile(path, newOpts);                        newOpts.inJustDecodeBounds = false;                        int w = newOpts.outWidth;                        int h = newOpts.outHeight;                        //现在主流手机比较多是1280*720分辨率,所以高和宽我们设置为                        //这里设置高度为1280f                        float hh = 1280f;                        //这里设置宽度为720f                        float ww = 720f;                        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可                        //be=1表示不缩放                        int 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(path, newOpts);                        //压缩好比例大小后再进行质量压缩                        ByteArrayOutputStream baos = new ByteArrayOutputStream();                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中                        int options = 100;                        while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩                            //重置baos即清空baos                            baos.reset();                            //这里压缩options%,把压缩后的数据存放到baos中                            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);                            options -= 10;//每次都减少10                        }                        int len = baos.toByteArray().length / 1024;                        tv3.setText("内存中的大小:" + len + "kb");                        //把压缩后的数据baos存放到ByteArrayInputStream中                        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());                        //把ByteArrayInputStream数据生成图片                        Bitmap bitmap3 = BitmapFactory.decodeStream(isBm, null, null);                        iv.setImageBitmap(bitmap3);                        /*File file5 = new File(Environment.getExternalStorageDirectory(), "load5.jpg");                        FileOutputStream out = new FileOutputStream(file5);                        out.write(baos.toByteArray());                        out.close();                        baos.close();*/                    }                });    }    private void load3() {        Observable.create(new ObservableOnSubscribe<String>() {            @Override            public void subscribe(ObservableEmitter<String> e) throws Exception {                ResponseBody body = new Retrofit.Builder()                        .baseUrl(baseUrl)                        .build()                        .create(NetServerInterface.class)                        .getBitmap(IMG_URL_1)                        .execute()                        .body();                contentLength = (int) body.contentLength() / 1024;                InputStream stream = body                        .byteStream();                Bitmap bitmap = BitmapFactory.decodeStream(stream);                ByteArrayOutputStream baos = new ByteArrayOutputStream();                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中                int options = 100;                while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩                    //重置baos即清空baos                    baos.reset();                    //这里压缩options%,把压缩后的数据存放到baos中                    bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);                    options -= 10;//每次都减少10                }                File file = new File(Environment.getExternalStorageDirectory(), "load3.jpg");                FileOutputStream out = new FileOutputStream(file);                out.write(baos.toByteArray());                out.close();                baos.close();                String filePath = file.getPath();                e.onNext(filePath);            }        })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String path) throws Exception {                        tvOld.setText("原始大小:" + contentLength + "kb");                        File file = new File(path);                        int fileLenth = (int) (file.length() / 1024);                        tv.setText("保存后大小:" + fileLenth + "kb");                        Bitmap bitmap = BitmapFactory.decodeFile(path);                        int byteCount = bitmap.getByteCount() / 1024;                        tv3.setText("加载到内存的大小:" + byteCount);                        iv.setImageBitmap(bitmap);                    }                });    }    private void load2() {        Observable.create(new ObservableOnSubscribe<String>() {            @Override            public void subscribe(ObservableEmitter<String> e) throws Exception {                ResponseBody body = new Retrofit.Builder()                        .baseUrl(baseUrl)                        .build()                        .create(NetServerInterface.class)                        .getBitmap(IMG_URL_1)                        .execute()                        .body();                contentLength = (int) body.contentLength() / 1024;                InputStream stream = body                        .byteStream();                //压缩100,图片并将Bitmap保存到本地                Bitmap bitmap = BitmapFactory.decodeStream(stream);                File file = new File(Environment.getExternalStorageDirectory(), "load2.jpg");                FileOutputStream out = new FileOutputStream(file);                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);                String filePath = file.getPath();                e.onNext(filePath);            }        })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String path) throws Exception {                        tvOld.setText("原始大小:" + contentLength + "kb");                        File file = new File(path);                        int fileLenth = (int) (file.length() / 1024);                        tv.setText("保存后大小:" + fileLenth + "kb");                        Bitmap bitmap = BitmapFactory.decodeFile(path);                        int byteCount = bitmap.getByteCount() / 1024;                        tv3.setText("加载到内存的大小:" + byteCount);                        iv.setImageBitmap(bitmap);                    }                });    }    private void load1() {        Observable.create(new ObservableOnSubscribe<String>() {            @Override            public void subscribe(ObservableEmitter<String> e) throws Exception {                ResponseBody body = new Retrofit.Builder()                        .baseUrl(baseUrl)                        .build()                        .create(NetServerInterface.class)                        .getBitmap(IMG_URL_1)                        .execute()                        .body();                contentLength = (int) body.contentLength() / 1024;                InputStream stream = body                        .byteStream();                //压缩图片并将Bitmap保存到本地//                Bitmap bitmap = BitmapFactory.decodeStream(stream);//                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);                File file = new File(Environment.getExternalStorageDirectory(), "load1.jpg");                FileOutputStream out = new FileOutputStream(file);                out.write(body.bytes());                out.close();                String filePath = file.getPath();                e.onNext(filePath);            }        })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String path) throws Exception {                        tvOld.setText("原始大小:" + contentLength + "kb");                        File file = new File(path);                        int fileLenth = (int) (file.length() / 1024);                        tv.setText("保存后大小:" + fileLenth + "kb");                        Bitmap bitmap = BitmapFactory.decodeFile(path);                        int byteCount = bitmap.getByteCount() / 1024;                        tv3.setText("加载到内存的大小:" + byteCount);                        iv.setImageBitmap(bitmap);                    }                });    }    private void load0() {        Observable                .create(new ObservableOnSubscribe<Bitmap>() {                    @Override   //订阅                    public void subscribe(ObservableEmitter<Bitmap> e) throws Exception {                        Response<ResponseBody> response = new Retrofit.Builder()                                .baseUrl(baseUrl)//地址                                .build()                                .create(NetServerInterface.class)//运行接口                                .getBitmap(IMG_URL_0)                                .execute();//异步线程                        contentLength = (int) (response.body().contentLength() / 1024);                        //IO读取流                        InputStream stream = response.body().byteStream();                        //位图                        Bitmap bitmap = BitmapFactory.decodeStream(stream);                        e.onNext(bitmap);                    }                }).subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer<Bitmap>() {                    @Override                    public void accept(Bitmap bitmap) throws Exception {                        tvOld.setText("原图片大小为:" + contentLength + "kb");                        iv.setImageBitmap(bitmap);                    }                });    }    protected Button btn;    protected TextView tv;    protected ImageView iv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        super.setContentView(R.layout.activity_main);        initView();    }    @Override    public void onClick(View view) {        if (view.getId() == R.id.btn) {            showList();        }    }    private void initView() {        btn = (Button) findViewById(R.id.btn);        btn.setOnClickListener(MainActivity.this);        tv = (TextView) findViewById(R.id.tv);        iv = (ImageView) findViewById(R.id.iv);        tvOld = (TextView) findViewById(R.id.tv_old);        tv3 = (TextView) findViewById(R.id.tv3);    }}