天天看點

Android裁剪圓形頭像源碼

最近項目上要加一個小功能,裁剪圖檔生成圓形頭像。我參考資料寫了個小demo,大家可以參考一下。下面是代碼,不難,容易有坑的地方稍微加了下注釋。

package com.example.cutpicturedemo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import java.io.File;

public class MainActivity extends Activity implements View.OnClickListener {
	private ImageView photo;
	private final int REQUEST_CODE_CAMERA = 1;
	private final int REQUEST_CODE_GALLERY = 2;
	private final int REQUEST_CODE_CUT_PHOTO = 3;
	private final int ACTION_CODE_CAMERA = -1;
	private final int ACTION_CODE_GALLERY = -2;
	private final String PHOTO_TEMP_PATH = "/Img/photo.jpg";
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		this.photo = ((ImageView) findViewById(R.id.photo));
		this.photo.setOnClickListener(this);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		switch (requestCode) {
		case REQUEST_CODE_CAMERA:
			File localFile = new File(Environment.getExternalStorageDirectory()
					+ MainActivity.this.PHOTO_TEMP_PATH);
			if(localFile.exists()){
				cutPhoto(Uri.fromFile(localFile));
			}
			break;
			//下面兩種情況需要檢查下data為空的情況
		case REQUEST_CODE_GALLERY:
			if (data != null) {
				cutPhoto(data.getData());
			}
			break;
		case REQUEST_CODE_CUT_PHOTO:
			if (data != null) {
				setPhoto(data);
			}
			break;
		default:
			break;
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	private void showPickDialog() {
		PickPhotoListener mPickPhotoListener = new PickPhotoListener();
		new AlertDialog.Builder(this)
				.setTitle("更換頭像")
				.setMessage("選擇圖檔")
				.setPositiveButton("相機", mPickPhotoListener)
				.setNegativeButton("圖庫", mPickPhotoListener)
				.create()
				.show();
	}

	public Bitmap getCirclePhoto(Bitmap paramBitmap) {
		Bitmap localBitmap = Bitmap.createBitmap(paramBitmap.getWidth(),
				paramBitmap.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas localCanvas = new Canvas(localBitmap);
		Paint localPaint = new Paint();
		Rect localRect = new Rect(0, 0, paramBitmap.getWidth(),
				paramBitmap.getHeight());
		localPaint.setAntiAlias(true);
		localPaint.setFilterBitmap(true);
		localPaint.setDither(true);
		localCanvas.drawARGB(0, 0, 0, 0);
		localCanvas.drawCircle(paramBitmap.getWidth() / 2,
				paramBitmap.getHeight() / 2, paramBitmap.getWidth() / 2,
				localPaint);
		//這個是利用了ProterDuffXfermode裁剪圖檔
		
		localPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
		localCanvas.drawBitmap(paramBitmap, localRect, localRect, localPaint);
		return localBitmap;
	}

	@Override
	public void onClick(View paramView) {
		showPickDialog();
	}

	public void cutPhoto(Uri paramUri) {
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(paramUri, "image/*")
			.putExtra("crop", "true")
			.putExtra("aspectX", 1)
			.putExtra("aspectY", 1)
			/*這裡注意一下,輸出圖檔的大小要控制一下
			 * 300 300指的是像素
			 * 因為輸出資料是通過Intent傳輸的
			 * 大小控制在360*360以内,但是太小圖檔就模糊了,建議在150~350之間
			 */
			.putExtra("outputX", 300)
			.putExtra("outputY", 300)
			.putExtra("return-data", true);
		startActivityForResult(intent, MainActivity.this.REQUEST_CODE_CUT_PHOTO);
	}

	public void setPhoto(Intent paramIntent) {
		Bundle localBundle = paramIntent.getExtras();
		if (localBundle != null) {
			Bitmap localBitmap = (Bitmap) localBundle.getParcelable("data");
			this.photo.setImageBitmap(getCirclePhoto(localBitmap));
//			this.photo.setImageBitmap(localBitmap);
			File localFile = new File(Environment.getExternalStorageDirectory()
					+ MainActivity.this.PHOTO_TEMP_PATH);
			if (localFile.exists()){
				localFile.delete();
				Log.v("delete photo", "down");
			}
		}
	}

	private class PickPhotoListener implements DialogInterface.OnClickListener {

		@Override
		public void onClick(DialogInterface paramDialogInterface, int actionCode) {
			
			if (actionCode == MainActivity.this.ACTION_CODE_CAMERA) {
				paramDialogInterface.dismiss();
				Intent intent = new Intent(
						"android.media.action.IMAGE_CAPTURE");
				intent.putExtra("output", Uri.fromFile(new File(
						Environment.getExternalStorageDirectory(),
						MainActivity.this.PHOTO_TEMP_PATH)));
				MainActivity.this.startActivityForResult(intent, MainActivity.this.REQUEST_CODE_CAMERA);
			}

			if (actionCode == MainActivity.this.ACTION_CODE_GALLERY) {
				paramDialogInterface.dismiss();
				Intent intent = new Intent("android.intent.action.PICK",
						null);
				intent.setDataAndType(
								MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
								"image/*");
				MainActivity.this.startActivityForResult(intent, MainActivity.this.REQUEST_CODE_GALLERY);
			}
		}
	}
}
           

源碼我就不上傳了,就這一個Activity,Layout就隻有一個ImageView子元素。

繼續閱讀