android luban压缩2中图片,安卓Matisse+Luban实现获取图片后再压缩

需要先添加依赖

implementation 'top.zibin:Luban:1.1.8'

在通过Matisse完成图片的选择后,获取到的Uri传入luban,luban无法找到图片,所以无法进行压缩

List pathList = Matisse.obtainResult(data);

因此通过Uri获取图片的路径后,再进行压缩

以下方式仅在安卓6.0验证过,其他版本不一定可行,请自行研究

/**

* 通过Uri获取文件路径

* @param pUri

* @return

*/

public String getPathByUri(Uri pUri)

{

// pUri.getPath()

// 拍照后输出: /mq_external_cache/storage/emulated/0/Pictures/JPEG_20190326_225011.jpg

// 选择照片后的输出: /external/images/media/52325

String _Path = pUri.getPath();

if (_Path.endsWith(".jpg"))

{

System.out.println("path-->" + subPath(_Path));

return subPath(_Path);

}

String[] filePathColumn = {MediaStore.Images.Media.DATA};

Cursor cursor = context.getContentResolver().query(pUri,

filePathColumn, null, null, null);

cursor.moveToFirst();

int columnIndex = cursor.getColumnIndex(filePathColumn[0]);

String picturePath = cursor.getString(columnIndex);

cursor.close();

return picturePath;

}

private String subPath(String pPath)

{

String[] array = pPath.split("/");

return pPath.substring(array[1].length() + 1, pPath.length());

}

配合安卓图片选择框架Matisse的使用后,完整的MainActivity代码如下

package com.jsf.piccompresstest;

import android.Manifest;

import android.content.Context;

import android.content.Intent;

import android.content.pm.ActivityInfo;

import android.database.Cursor;

import android.graphics.BitmapFactory;

import android.net.Uri;

import android.os.Build;

import android.os.Environment;

import android.provider.MediaStore;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.text.TextUtils;

import android.util.Log;

import android.view.View;

import android.widget.ImageView;

import android.widget.Toast;

import com.bumptech.glide.Glide;

import com.tbruyelle.rxpermissions2.RxPermissions;

import com.zhihu.matisse.Matisse;

import com.zhihu.matisse.MimeType;

import com.zhihu.matisse.filter.Filter;

import com.zhihu.matisse.internal.entity.CaptureStrategy;

import com.zhihu.matisse.internal.entity.IncapableCause;

import com.zhihu.matisse.internal.entity.Item;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

import io.reactivex.functions.Consumer;

import top.zibin.luban.CompressionPredicate;

import top.zibin.luban.Luban;

import top.zibin.luban.OnCompressListener;

/**

* 参考 https://blog.csdn.net/qq_36043263/article/details/81707029

*/

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

private ImageView mView;

private final int REQUEST_CODE_CHOOSE_PHOTO_ALBUM = 1;

public static final String SD_APP_DIR_NAME = "TestDir"; //存储程序在外部SD卡上的根目录的名字

public static final String PHOTO_DIR_NAME = "photo"; //存储照片在根目录下的文件夹名字

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

findViewById(R.id.btn_select_pic).setOnClickListener(this);

mView = findViewById(R.id.iv_photo);

initPermission();

}

private void initPermission()

{

RxPermissions rxPermissions=new RxPermissions(this);

rxPermissions.request(

Manifest.permission.CAMERA

,Manifest.permission.WRITE_EXTERNAL_STORAGE

,Manifest.permission.READ_EXTERNAL_STORAGE

).subscribe(new Consumer() {

@Override

public void accept(Boolean aBoolean) throws Exception {

if (aBoolean){

//申请的权限全部允许

// Toast.makeText(MainActivity.this, "允许了权限!", Toast.LENGTH_SHORT).show();

}else{

//只要有一个权限被拒绝,就会执行

// Toast.makeText(MainActivity.this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();

}

}

});

}

@Override

public void onClick(View view) {

switch (view.getId())

{

case R.id.btn_select_pic:

selectPic();

break;

}

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == REQUEST_CODE_CHOOSE_PHOTO_ALBUM && resultCode == RESULT_OK)

{

//图片路径 同样视频地址也是这个 根据requestCode

List pathList = Matisse.obtainResult(data);

List _List = new ArrayList<>();

for (Uri _Uri : pathList)

{

String _Path = getPathByUri(_Uri);

File _File = new File(_Path);

System.out.println("压缩前图片大小->" + _File.length() / 1024 + "k");

_List.add(_Path);

}

compress(_List);

}

}

private void compress(List list)

{

String _Path = getImagesPath();

System.out.println("_Path->" + _Path);

Luban.with(this)

.load(list)

.ignoreBy(100)

.setTargetDir(_Path)

.filter(new CompressionPredicate() {

@Override

public boolean apply(String path) {

return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));

}

})

.setCompressListener(new OnCompressListener() {

@Override

public void onStart() {

// TODO 压缩开始前调用,可以在方法内启动 loading UI

Toast.makeText(MainActivity.this, "I'm start", Toast.LENGTH_SHORT).show();

}

@Override

public void onSuccess(File file) {

// TODO 压缩成功后调用,返回压缩后的图片文件

Glide.with(MainActivity.this).load(file).into(mView);

System.out.println("压缩后图片大小->" + file.length() / 1024 + "k");

System.out.println("getAbsolutePath->" + file.getAbsolutePath());

}

@Override

public void onError(Throwable e) {

// TODO 当压缩过程出现问题时调用

e.printStackTrace();

}

}).launch();

}

void selectPic()

{

Matisse.from(this)

.choose(MimeType.ofImage(), false)

.capture(true) // 使用相机,和 captureStrategy 一起使用

.captureStrategy(new CaptureStrategy(true, "com.jsf.piccompresstest123"))

// R.style.Matisse_Zhihu (light mode)

// R.style.Matisse_Dracula (dark mode)

.theme(R.style.Matisse_Dracula)

.countable(true)

.maxSelectable(1)

.addFilter(new Filter() {

@Override

protected Set constraintTypes() {

return new HashSet() {{

add(MimeType.PNG);

}};

}

@Override

public IncapableCause filter(Context context, Item item) {

try {

InputStream inputStream = getContentResolver().openInputStream(item.getContentUri());

BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeStream(inputStream, null, options);

int width = options.outWidth;

int height = options.outHeight;

// if (width >= 500)

// return new IncapableCause("宽度超过500px");

} catch (FileNotFoundException e) {

e.printStackTrace();

}

return null;

}

})

// .gridExpectedSize((int) getResources().getDimension(R.dimen.imageSelectDimen))

.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)

.thumbnailScale(0.87f)

.imageEngine(new GlideLoadEngine())

.forResult(REQUEST_CODE_CHOOSE_PHOTO_ALBUM);

}

/**

* 通过Uri获取文件路径

* @param pUri

* @return

*/

public String getPathByUri(Uri pUri)

{

// pUri.getPath()

// 拍照后输出: /mq_external_cache/storage/emulated/0/Pictures/JPEG_20190326_225011.jpg

// 选择照片后的输出: /external/images/media/52325

String _Path = pUri.getPath();

if (_Path.endsWith(".jpg"))

{

System.out.println("path-->" + subPath(_Path));

return subPath(_Path);

}

String[] filePathColumn = {MediaStore.Images.Media.DATA};

Cursor cursor = context.getContentResolver().query(pUri,

filePathColumn, null, null, null);

cursor.moveToFirst();

int columnIndex = cursor.getColumnIndex(filePathColumn[0]);

String picturePath = cursor.getString(columnIndex);

cursor.close();

return picturePath;

}

private String subPath(String pPath)

{

String[] array = pPath.split("/");

return pPath.substring(array[1].length() + 1, pPath.length());

}

private String getImagesPath()

{

return createPathIfNotExist("/" + SD_APP_DIR_NAME + "/" + PHOTO_DIR_NAME);

}

private String createPathIfNotExist(String pPath)

{

boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState());

if (!sdExist) {

Log.e("path", "SD卡不存在");

return null;

}

String _AbsolutePath = android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + pPath;

System.out.println("dbDir->" + _AbsolutePath);

File dirFile = new File(_AbsolutePath);

if (!dirFile.exists()) {

if (!dirFile.mkdirs())

{

Log.e("path", "文件夹创建失败");

return null;

}

}

return _AbsolutePath;

}

}

Luban(鲁班)——Android图片压缩工具,仿微信朋友圈压缩策略。项目描述目前做app开发总绕不开图片这个元素。但是随着手机拍照分辨率的提升,图片压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经有很多文章介绍。但是裁切成多少,压缩成多少却很难控制好,裁切过头图片太小,质量压缩过头则显示效果太差。于是自然想到app巨头“微信”会是怎么处理,Luban(鲁班)就是通过在微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。因为有其他语言也想要实现 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导入compile 'io.reactivex:rxandroid:1.2.1' compile 'io.reactivex:rxjava:1.1.6' compile 'top.zibin:Luban:1.0.5'使用Listener方式Luban内部采用io线程进行图片压缩,外部调用只需设置好结果监听即可Luban.get(this)     .load(File)                     //传人要压缩图片     .putGear(Luban.THIRD_GEAR)      //设定压缩档次,默认三挡     .setCompressListener(new OnCompressListener() { //设置回调         @Override         public void onStart() {             //TODO 压缩开始前调用,可以在方法内启动 loading UI         }         @Override         public void onSuccess(File file) {             //TODO 压缩成功后调用,返回压缩后的图片文件         }         @Override         public void onError(Throwable e) {             //TODO 当压缩过去出现问题时调用         }     }).launch();    //启动压缩RxJava方式RxJava 调用方式请自行随意控制线程Luban.get(this)         .load(file)         .putGear(Luban.THIRD_GEAR)         .asObservable()         .subscribeOn(Schedulers.io())         .observeOn(AndroidSchedulers.mainThread())         .doOnError(new Action1() {             @Override             public void call(Throwable throwable) {                 throwable.printStackTrace();             }         })         .onErrorResumeNext(new Func1>() {             @Override             public Observable<? extends File> call(Throwable throwable) {                 return Observable.empty();             }         })         .subscribe(new Action1() {             @Override             public void call(File file) {                 //TODO 压缩成功后调用,返回压缩后的图片文件             }         }); 标签:Luban(鲁班)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值