Android之圓形頭像(實現相機拍攝+相冊選擇+圖片裁剪功能)

 

轉載請標明出處https://my.oschina.net/FlyinTang/blog/751595java

最近的一些學習心得android

功能實現:點擊圓形頭像以後能夠實現相冊上傳或者開啓相機,而後把獲得的圖片通過剪裁,把剪裁過的圖片設置爲頭像的背景圖

步驟:第一步:自定義一個類,繼承ImageView,重寫draw方法,實現外觀爲圓形canvas

第二步:在xml文件中引用該控件ide

第三步:實現圓形頭像的點擊事件,點擊後顯示對話框界面,詢問你是打開相冊仍是相機(自動省略顯示對話框的代碼)學習

第四步:根據用戶選擇狀況,打開相冊或者相機ui

第五步:將拍攝的圖片或者相冊選中的圖片進行剪裁,將結果保存在指定內存區域this

第六步:更新頭像圖片spa

 

具體實現:第一步:自定義一個類,繼承ImageView,重寫draw方法,實現外觀爲圓形.net

//圓形頭像類
public class MyRoundPhoto extends ImageView{

	private Paint p;
	private Bitmap bitmap;
	private Context context;
	private int wAndHeight[]=new int[2];
	private File file;
	
	public MyRoundPhoto(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		
		//得到控件長寬(px)
		wAndHeight = getWidthAndHeight(context,attrs);
		
		this.context = context;
		
        //初始化控件
        init();
		
		

	}

	public MyRoundPhoto(Context context) {
		super(context);
		// TODO Auto-generated constructor stub

        //得到控件長寬(px)
		wAndHeight=getWidthAndHeight(context,attrs);
		
		this.context = context;
		init();
	}

	public MyRoundPhoto(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		//得到控件長寬(px)
		wAndHeight=getWidthAndHeight(context,attrs);
		
		// TODO Auto-generated constructor stub
		this.context = context;
		init();
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		canvas.drawBitmap(bitmap, new Matrix(), p);
		
	}
	
	private void init(){
		//從手機存儲區域獲取圖片文件(該位置爲手機相冊選中的圖片通過剪裁後的圖片的存儲路徑)
		file = new File(Environment.getExternalStorageDirectory(),Info.PHOTO_NAME);
		
        //若是圖片文件存在,則顯示,不然則建立並顯示
		if(file.exists()){
			Log.v("文件存在", "是");
			this.bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
		}
		else{
			Log.v("文件不存在", "是");
			
			//生成默認圖片的文件
			this.bitmap=BitmapFactory.decodeStream(context.getResources().openRawResource(R.drawable.defalut));
			//person.setPicture()
			FileOutputStream fos=null;
			try {
				fos = new FileOutputStream(file);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); //壓縮
			try {
				fos.flush();
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
		//將方形的位圖轉換爲圓形的位圖
		this.bitmap = toRoundBitmap(this.bitmap);
		p = new Paint();
			
	}
	
	private Bitmap toRoundBitmap(Bitmap map){
		
		
		//int height = map.getHeight()+100;
		int height=convertDIP2PX(context,this.wAndHeight[1]); //位圖的高度(px)
		int width = convertDIP2PX(context,this.wAndHeight[0]);//位圖的寬度(px)
		
		//建立畫布
		Bitmap bit = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		Canvas canvas = new Canvas(bit);
		
		//畫筆
		Paint paint = new Paint();
		paint.setAntiAlias(false);
		int r = (width>height)?height:width;
		
		
		
		//繪製圓形
		RectF rectF = new RectF(0,0,r,r);
		canvas.drawRoundRect(rectF, r/2, r/2, paint);
		
		//畫頭像
		//canvas.drawARGB(0, 0, 0, 0);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(map, null,rectF, paint);
		
		//返回圓形位圖
		return bit;
	}
	
    //使當前視圖無效,從而使系統從新繪製視圖
	public void myValidate(){
		bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
		bitmap=toRoundBitmap(bitmap);
		invalidate();
		
	}
	
    //將dp轉換爲px
	private static int convertDIP2PX(Context context, int dip) { 
	    float scale = context.getResources().getDisplayMetrics().density; 
	    return (int)(dip*scale + 0.5f*(dip>=0?1:-1)); 
	} 
	
	//根據xml文件中的屬性,返回寬高(px)
    private static int[] getWidthAndHeight(Context context,AttributeSet attrs){
		int height,width;
		int n = attrs.getAttributeCount();
		int wAndH[] = new int[2];
		
		
		for(int i=0;i<n;i++){
			String str = attrs.getAttributeName(i);
			
			//獲取寬度
			if(str.equals("layout_width")){				
				//System.out.println(attrs.getAttributeName(0));
				String sttr = attrs.getAttributeValue(i);
				String temp = "";
				int j=0;
				while(sttr.charAt(j)>='0'&&sttr.charAt(j)<='9'){
					temp+=sttr.charAt(j);
					j++;
				}
				wAndH[0]=Integer.parseInt(temp);
				temp="";
				continue;
			}
			
			//獲取長度
			if(str.equals("layout_height")){
				//System.out.println(attrs.getAttributeName(1));
				String sttr = attrs.getAttributeValue(i);
				String temp = "";
				int j=0;
				while(sttr.charAt(j)>='0'&&sttr.charAt(j)<='9'){
					temp+=sttr.charAt(j);
					j++;
				}
				//System.out.println("temp"+temp);
				wAndH[1]=Integer.parseInt(temp);
				temp="";
				continue;
			}
		}
		return wAndH;
	}	
}

第二步:在xml文件中引用該控件

<com.包名.MyRoundPhoto
          		android:id="@+id/myRoundPhoto"
                android:layout_width="100dp"
                android:layout_height="100dp"  >
                
            </com.包名.MyRoundPhoto>

第三步:實現圓形頭像的點擊事件,點擊後顯示對話框界面,詢問你是打開相冊仍是相機(自動省略顯示對話框的代碼)

public void onClick(View v) {
		// TODO Auto-generated method stub
		
		//點擊頭像
		if(v.getId()==R.id.myRoundPhoto){
			//打開DialogActivity,詢問打開照相機仍是相冊
			Intent intent = new Intent(GuideActivity.this,DialogActivity.class);
			startActivityForResult(intent, Info.PICK_PHOTO);
		}
	}

 第四步:根據用戶選擇狀況,打開相冊或者相機

image =new File(Environment.getExternalStorageDirectory(),Info.PHOTO_NAME);

    public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		
		//打開相機
		case R.id.imageButton1:{
			Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
			intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
			startActivityForResult(intent, Info.OPEN_CAMERA);		
			break;
		}
		
		//打開相冊
		case R.id.imageButton2:{
			Intent intent = new Intent(Intent.ACTION_PICK);
			intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
			intent.setType("image/*");
			startActivityForResult(intent, Info.OPEN_GALLERY);
			break;
		}
		}
	}

第五步:將拍攝的圖片或者相冊選中的圖片進行剪裁,將結果保存在指定內存區域

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		
		switch(requestCode){
		//打開相機	
		case Info.OPEN_CAMERA:{
			if(resultCode==RESULT_OK){
				
				//啓動裁剪activity
				Log.v("啓動剪裁程序", "是的");
				Intent intent1 = new Intent("com.android.camera.action.CROP");
	            intent1.setDataAndType(Uri.fromFile(image), "image/*");
	            intent1.putExtra("crop", "true");
	            intent1.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));//
	            intent1.putExtra("aspectX", 1);
	            intent1.putExtra("aspectY", 1);
	            intent1.putExtra("outputFormat", Bitmap.CompressFormat.JPEG);
	            intent1.putExtra("outputX", 720);
	            intent1.putExtra("outputY", 720);
	            intent1.putExtra("return-data", false);
	            startActivityForResult(intent1, Info.CROP_PHOTO);
			}
			break;
		}
		
		//打開相冊
		case Info.OPEN_GALLERY:{
			
			if(resultCode==RESULT_OK){		
				//啓動剪裁程序
				Log.v("啓動剪裁程序", "是的");
				Intent intent1 = new Intent("com.android.camera.action.CROP");
	            intent1.setDataAndType(Uri.fromFile(image), "image/*");
	            intent1.putExtra("crop", "true");
	            intent1.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));//
	            intent1.putExtra("aspectX", 1);
	            intent1.putExtra("aspectY", 1);
	            intent1.putExtra("outputFormat", Bitmap.CompressFormat.JPEG);
	            intent1.putExtra("outputX", 720);
	            intent1.putExtra("outputY", 720);
	            intent1.putExtra("return-data", false);
	            startActivityForResult(intent1, Info.CROP_PHOTO);
			}		
			break;
		}
		
		//裁剪圖片
		case Info.CROP_PHOTO:{
			Intent intent=new Intent();
			setResult(this.RESULT_OK, intent);
			finish();
			break;
		}
		}
	}

第六步:更新頭像圖片

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		
		switch(requestCode){
		//選擇頭像
		case Info.PICK_PHOTO:{
			//若是攝取圖片成功
			if(resultCode==RESULT_OK){
				Log.v("requstCodeGuideOne", "PICK_PHOTO");
				btn_choosePhoto.myValidate(); //使原有視圖無效,從而使系統從新繪製視圖
			}
			break;
		}
		
		default:{
			break;
		}
		}
	}

注意:須要添加的權限

<uses-permission  
        android:name="android.permission.READ_EXTERNAL_STORAGE"  
        />  
<uses-permission  
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
相關文章
相關標籤/搜索