码迷,mamicode.com
首页 > 其他好文 > 详细

第三讲 ------- 从系统中选择图片(拍照或从相册中取)

时间:2015-03-03 18:38:52      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:android   相机   相册   裁剪   

              从系统中取图片这个是写安卓非常常见的一个功能,但是很多时候我们每次我们都去写一个还是比较麻烦的。

              下面我就介绍我写的一个已经封装好的一个类,先看截图技术分享

              从截图上看,功能很清晰,点击获取图片按钮,出来一个半透明的界面,具有用相机拍照获取图片和从相册中选择两种途径去获取图片。

              看完截图直接上代码

           

package com.yixuan;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.example.handlertest.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

/**
 * 
 * <p>
 * 描 述:由于很多时候获取照片是从fragment中过来的,所以不好用activity的onResult
 * 方式解决,在一个静态类里面设置一个变量存放获取到的图片路径
 * 
 * <p>
 * 创 建 人:ztt
 * </p>
 * <p>
 * 创建时间:2015-2-4下午1:45:21
 * </p>
 */
public abstract class PickPhotoActivity extends Activity implements
		OnClickListener {
	/* activity返回的回调类型 */
	public static final int PHOTO_PICKED_WITH_GALLERY = 9001;
	public static final int PHOTO_PICKED_WITH_CAMERA = 9002;
	public static final int CROPED_PHOTO = 9003;
	private final int cropWidth = 160;
	private final int cropHeight = 160;
	private Activity act;
	private boolean doCrop = true;
	protected int width;
	protected int height;
	protected int DEFAULT_WIDTH = 480;
	protected int DEFAULT_HEIGHT = 480;
	protected Context ctx;
	private int dpi;
	private int screenWidth;
	protected static String picPath;/* 取得的图片路径 */

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pick_photo);
		ctx = this;
		Intent intent = getIntent();
		DisplayMetrics metric = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metric);
		float density = metric.density;
		dpi = (int) (metric.densityDpi * density);
		DEFAULT_WIDTH = metric.widthPixels;
		DEFAULT_HEIGHT = metric.heightPixels;
		// String path = intent.getStringExtra("tempPath");
		doCrop = intent.getBooleanExtra("doCrop", true);
		width = intent.getIntExtra("width", DEFAULT_WIDTH);
		height = intent.getIntExtra("height", DEFAULT_HEIGHT);
		File picturePathFile = new File(getPicPath());
		if (!picturePathFile.exists()) {
			picturePathFile.mkdirs();
		}
		screenWidth = metric.widthPixels;
		// DEFAULT_WIDTH = getScale() * 2;
		// DEFAULT_HEIGHT = getScale() * 2;
		System.out.println(getScale() * 2);
		initView();
	}

	private int getScale() {
		Double val = 4d * dpi / screenWidth;
		val = val * 100d;
		return val.intValue();
	}

	private void initView() {
		findViewById(R.id.pick_photo_from_camera).setOnClickListener(this);
		findViewById(R.id.pick_photo_from_gallery).setOnClickListener(this);
		findViewById(R.id.cancel).setOnClickListener(this);
		act = this;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
			case PHOTO_PICKED_WITH_CAMERA:
				if (doCrop) {
					doCropPhoto(new File(getFullPath()), cropWidth, cropHeight);

				} else {
					savePicture(picPath, null);
				}
				break;
			case PHOTO_PICKED_WITH_GALLERY:
				picPath = getPathFromURI(data.getData().toString());
				if (doCrop) {
					doCropPhoto(new File(picPath), cropWidth, cropHeight);
				} else {
					savePicture(picPath, null);
				}
				break;
			case CROPED_PHOTO:
				Bitmap img = data.getParcelableExtra("data");
				// ImageTools.savePhotoToSDCard(img, getPicPath(),
				// getTempImageName());
				savePicture(null, img);
				break;
			default:
				break;
			}

		} else {
			clearFullPath();
		}
	}

	public static void clearFullPath() {
		picPath = null;
	}

	public String getPicPath() {
		return Environment.getExternalStorageDirectory().toString() + "/";
	}

	private void savePicture(String picturePath, Bitmap bitmap) {
		Bitmap photo = null;
		try {
			if (bitmap == null) {
				photo = decodeBitmap(picturePath, width, height);
			} else {
				photo = bitmap;
			}
			savePictrue(photo);
			if (photo != null && !photo.isRecycled()) {
				photo.recycle();
			}
			picPath = getPicPath() + getTempImageName();
			afterSavePhoto(getFullPath());
			File file = new File(getFullPath());
			if (file.exists()) {
				file.delete();
			}
		}

		catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getFullPath() {
		return picPath;
	}

	protected abstract void afterSavePhoto(String picPath);

	private void savePictrue(Bitmap newBitmap) {
		savePhotoToSDCard(newBitmap, getPicPath(), getTempImageName());
	}

	public static void savePhotoToSDCard(Bitmap photoBitmap, String path,
			String photoName) {
		if (checkSDCardAvailable()) {
			File dir = new File(path);
			if (!dir.exists()) {
				dir.mkdirs();
			}

			File photoFile = new File(path, photoName);
			FileOutputStream fileOutputStream = null;
			try {
				fileOutputStream = new FileOutputStream(photoFile);
				if (photoBitmap != null) {
					if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100,
							fileOutputStream)) {
						fileOutputStream.flush();
					}
				}
			} catch (FileNotFoundException e) {
				photoFile.delete();
				e.printStackTrace();
			} catch (IOException e) {
				photoFile.delete();
				e.printStackTrace();
			} finally {
				try {
					fileOutputStream.close();
					photoBitmap.recycle();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.pick_photo_from_camera) {
			takePickture();
		} else if (v.getId() == R.id.pick_photo_from_gallery) {
			getPicktureFromGallery();
		} else {
			finish();
		}
		// switch(v.getId()){
		// case R.id.pick_photo_from_camera:
		// break;
		// }
		// switch (v.getId()) {
		// case R.id.pick_photo_from_camera:
		// takePickture();
		// break;
		// case R.id.pick_photo_from_gallery:
		// getPicktureFromGallery();
		// break;
		// case R.id.cancel:
		// finish();
		// break;
		// }
	}

	public static boolean checkSDCardAvailable() {
		return android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED);
	}

	private void getPicktureFromGallery() {
		Intent openAlbumIntent = new Intent(Intent.ACTION_PICK);
		openAlbumIntent.setType("image/*");
		startActivityForResult(openAlbumIntent, PHOTO_PICKED_WITH_GALLERY);
	}

	private void takePickture() {
		Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		picPath = getPicPath() + getTempImageName();
		Uri imageUri = Uri.fromFile(new File(picPath));
		openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
		if (doCrop) {
			openCameraIntent.putExtra("return-data", true);
		}
		startActivityForResult(openCameraIntent, PHOTO_PICKED_WITH_CAMERA);
	}

	protected static String getTempImageName() {
		return "IMG_" + "TEMP" + ".png";
		// return FileUtil.getTempPath() + AppConstants.DEFAULT_PIC_NAME;
	}

	@SuppressWarnings("deprecation")
	public String getPathFromURI(String stringExtra) {
		Uri uri = Uri.parse(stringExtra);
		String[] proj = { MediaStore.Images.Media.DATA };
		android.database.Cursor actualimagecursor = PickPhotoActivity.this
				.managedQuery(uri, proj, null, null, null);
		int actual_image_column_index = actualimagecursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		actualimagecursor.moveToFirst();
		String img_path = actualimagecursor
				.getString(actual_image_column_index);
		return img_path;
	}

	public Bitmap decodeBitmap(String path, int width, int height) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		// 通过这个bitmap获取图片的宽和高       
		Bitmap bitmap = BitmapFactory.decodeFile(path, options);
		if (bitmap == null) {
			System.out.println("bitmap为空");
		}
		float realWidth = options.outWidth;
		float realHeight = options.outHeight;
		System.out.println("真实图片高度:" + realHeight + "宽度:" + realWidth);
		int scale = Math.max((int) (realWidth / width),
				(int) (realHeight / height));
		if (scale <= 1) {
			scale = 1;
		}
		options.inSampleSize = scale;
		options.inJustDecodeBounds = false;
		// 注意这次要把options.inJustDecodeBounds 设为 false,这次图片是要读取出来的。  
		//    
		bitmap = BitmapFactory.decodeFile(path, options);
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		System.out.println("缩略图高度:" + h + "宽度:" + w);
		return bitmap;
	}

	private void doCropPhoto(File f, int outWith, int outHeight) {
		try {
			// 启动gallery去剪辑这个照片
			final Intent intent = getCropImageIntent(Uri.fromFile(f), outWith,
					outHeight);
			if (act != null)
				act.startActivityForResult(intent, CROPED_PHOTO);
			else
				act.startActivityForResult(intent, CROPED_PHOTO);
		} catch (Exception e) {
			Toast.makeText(act, act.getString(R.string.get_picture_failed),
					Toast.LENGTH_LONG).show();
		}
	}

	private Intent getCropImageIntent(Uri photoUri, int cropWidth,
			int cropHeight) {
		Intent intent = new Intent("com.android.camera.action.CROP")
				.setDataAndType(photoUri, "image/*").putExtra("crop", "true")
				.putExtra("return-data", true);
		intent.putExtra("aspectX", cropWidth);
		intent.putExtra("aspectY", cropHeight);
		intent.putExtra("outputX", cropWidth);
		intent.putExtra("outputY", cropHeight);
		return intent;

	}

}


             这个类很长,可能很多人不愿去看,如果觉得界面还凑合的就直接用吧,下面我再如何使用

            这个类是一个抽象类,它有抽象方法afterSavePhoto(String picPath),这个方法是选择图片之后会执行的,picPath是选择后的图片所在的位置。所以要用的话,只要自己写一个类并实现该方法,在方法中写上选好图片要做的事就可以了

            调用这个类也很简单,像下面这样

          

/**
	 * 不需要裁剪
	 */
	private void takePhoto() {
		Intent intent = new Intent(this, PhotoTestActicity.class);
		intent.putExtra("doCrop", false);
		this.startActivity(intent);
	}
	
	/**
	 * 选好图片后需要进行裁剪
	 */
	private void takePhotoCrop() {
		Intent intent = new Intent(this, PhotoTestActicity.class);
		
		this.startActivity(intent);
	}

在不需要裁剪的时候通过intent的bundle传递标识变量doCrop过去,这时候就不需要裁剪了


总结:这个网上有很多例子,但觉得方便的同学,欢迎使用

代码地址:http://download.csdn.net/detail/u010047390/8469665


     


第三讲 ------- 从系统中选择图片(拍照或从相册中取)

标签:android   相机   相册   裁剪   

原文地址:http://blog.csdn.net/u010047390/article/details/44040637

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!