Android項目實踐——三行代碼解決照片選擇與壓縮

版權聲明:本文爲博主原創文章,未經博主容許不得轉載java

系列教程:Android開發之從零開始系列android

源碼:AnliaLee/PhotoFactory,歡迎stargit

你們要是看到有錯誤的地方或者有啥好的建議,歡迎留言評論github

初看標題是否是以爲博主是標題黨,故意把大家騙了進來?告訴你bash

博主幫你們封裝好了PhotoFactory類,只需三行代碼就能夠完成選擇照片,獲取其bitmap或uri路徑(可自行配置是否壓縮)的功能。下面來看下如何使用PhotoFactoryapp


PhotoFactory簡介

使用PhotoFactory分爲三步,首先咱們要實例化一個photoFactoryide

PhotoFactory photoFactory = new PhotoFactory(this, this);//(Activity activity,Context context)
複製代碼

設置選擇照片的方式post

//提供三種選擇照片的方式
photoFactory.FactoryStart().SetStartType(PhotoFactory.TYPE_PHOTO_UNTREATED).Start();//調用相機拍照,照相後返回高清原圖相片
/*photoFactory.FactoryStart().SetStartType(PhotoFactory.TYPE_PHOTO_AUTO_COMPRESS).Start();//調用相機拍照,照相後返回系統自動壓縮過的相片 photoFactory.FactoryStart().SetStartType(PhotoFactory.TYPE_PHOTO_FROM_GALLERY).Start();//從本地相冊中選取圖片*/
複製代碼

獲取相片bitmap或uriui

/** * 在onActivityResult中調用此方法 */
photoFactory.FactoryFinish(requestCode,resultCode,data).GetBitmap();
//photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
複製代碼

就這麼簡單,固然,你還能夠對照片進行壓縮處理,這裏提供了三種壓縮的方式this

addScaleCompress(int w, int h)//按目標寬高縮放
addScaleCompress(int scale)//等比例縮放,縮放比爲 原圖:新圖 = scale:1
addQualityCompress(int targetSize)//質量壓縮,targetSize爲目標大小
複製代碼

你能夠選擇其中一種或多種壓縮方式對相片進行壓縮,例如

//只選擇一種壓縮方式
photoFactory.FactoryFinish(requestCode,resultCode,data)
	    .addQualityCompress(128)
	    .GetBitmap();
	    
//按順序逐步壓縮
photoFactory.FactoryFinish(requestCode,resultCode,data)
	    .addQualityCompress(128)
	    .addScaleCompress(5)
	    .addScaleCompress(300,300)
	    .GetBitmap();
複製代碼

完整示例

PhotoFactory兼容了Android 7.0 FileProvider獲取相片uri的問題,固然具體Provider的配置以及Android 6.0的動態權限管理須要你們在項目中自行完成。這裏爲了方便你們完成配置,我將完整的流程貼出來供你們參考

1.在Github下載photofactory library並導入到你的項目中

地址:AnliaLee/PhotoFactory

2. 在res\xml目錄中建立provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>
複製代碼

3. 在AndroidManifest.xml中添加相應權限及配置Provider

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
	android:icon="@mipmap/ic_launcher"
	...
	>
	<provider
		android:name="android.support.v4.content.FileProvider"
		android:authorities="${applicationId}.provider"
		android:exported="false"
		android:grantUriPermissions="true">
		<meta-data
			android:name="android.support.FILE_PROVIDER_PATHS"
			android:resource="@xml/provider_paths" />
	</provider>
	...
</application>
複製代碼

4. 在AndroidManifest.xml中添加相應權限及配置Provider

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
	android:icon="@mipmap/ic_launcher"
	...
	>
	<provider
		android:name="android.support.v4.content.FileProvider"
		android:authorities="${applicationId}.provider"
		android:exported="false"
		android:grantUriPermissions="true">
		<meta-data
			android:name="android.support.FILE_PROVIDER_PATHS"
			android:resource="@xml/provider_paths" />
	</provider>
	...
</application>
複製代碼

5. 在Activity中進行動態權限管理以及使用PhotoFactory

public class PhotoTestActivity extends AppCompatActivity {
    private Button btnPhoto;
    private ImageView imgPhoto;
    private PhotoFactory photoFactory;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photo_test);

        photoFactory = new PhotoFactory(this,this);
        imgPhoto = (ImageView) findViewById(R.id.img_photo);
        btnPhoto = (Button) findViewById(R.id.btn_photo);
        btnPhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(PhotoTestActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    //申請寫入權限
                    ActivityCompat.requestPermissions(PhotoTestActivity.this, new String[]{
                            Manifest.permission.WRITE_EXTERNAL_STORAGE
                    }, 100);
                } else {
                    photoFactory.FactoryStart()
                                .SetStartType(PhotoFactory.TYPE_PHOTO_UNTREATED)
                                .Start();
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch(requestCode) {
            case 100:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    photoFactory.FactoryStart()
                            .SetStartType(PhotoFactory.TYPE_PHOTO_UNTREATED)
                            .Start();
                }else{// 沒有獲取到權限,作特殊處理
                    Toast.makeText(this, "請授予權限!", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == RESULT_CANCELED){
            Toast.makeText(this, "取消拍照!", Toast.LENGTH_SHORT).show();
        }else {
            if(data == null){
                Toast.makeText(this, "取消選擇!", Toast.LENGTH_SHORT).show();
                return;
            }
            //使用你選取的照片
            Uri uri = photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
            imgPhoto.setImageURI(uri);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}
複製代碼

PhotoFactory至此介紹完畢,具體實現並不複雜,有興趣瞭解內部是如何實現的能夠自行查閱源碼,若是有不懂的地方或者檢查到代碼有什麼問題歡迎給我留言~


更新

以前的代碼雖然簡化了選取照片的過程,但沒有考慮到把取消選擇的處理也封裝進來,用戶還得在onActivityResult中寫一堆代碼去處理取消選擇的狀況,這說明PhotoFactory用起來還不夠方便,因而我動手增長了判斷取消選擇的接口,如今咱們能夠調用這些新的接口進行容錯了

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	//依然能夠這樣去獲取相片,但須要你本身去寫取消選擇的處理
	Uri uri = photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
	imgPhoto.setImageURI(uri);

	//如今只要這樣調用setOnResultListener就能夠一步到位了
	photoFactory.FactoryFinish(requestCode,resultCode,data)
				.setOnResultListener(new PhotoFactory.OnResultListener() {
		@Override
		public void TakePhotoCancel() {
			Toast.makeText(PhotoTestActivity.this, "取消拍照", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void GalleryPhotoCancel() {
			Toast.makeText(PhotoTestActivity.this, "取消選擇", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void HasData(PhotoFactory.FinishBuilder resultData) {//正確選取了相片
			Uri uri = resultData.GetUri();
			imgPhoto.setImageURI(uri);
		}
	});
	super.onActivityResult(requestCode, resultCode, data);
}
複製代碼

可是...這樣好像就不止三行代碼了啊...

相關文章
相關標籤/搜索