android本地图片选择(相册选取,相机拍摄)
2014-10-31 23:51
435 查看
最近由于项目的需要,要求用户可以上传自己拍的照片和图库中的已有照片,这是一个App比较基础性的功能,就索性将整个功能抽出来写成一个组件,以方面其它的App再实现此功能时可直接拿来使用.
话不多说,先看一下效果图,弹出选择方式window :
点击:Select from gallery,从本地机册中选择图片,如图:
点击:Take a photot就不再上传截图了.
下面将实现的主要代码出,如有需要可稍做修改即可做为一个组件使用,以下没布局文件.
话不多说,先看一下效果图,弹出选择方式window :
点击:Select from gallery,从本地机册中选择图片,如图:
点击:Take a photot就不再上传截图了.
下面将实现的主要代码出,如有需要可稍做修改即可做为一个组件使用,以下没布局文件.
public class TakePhoto { protected Activity mActivity; protected Intent mIntent = null; protected static final int PHOTO_REQUEST_TAKEPHOTO = 0x00000001; protected static final int PHOTO_REQUEST_CUT = 0x00000002; protected Uri currentUri = null; protected TakePhotoListener mTakePhotoListener; protected View mDisplayView; private String sdcardPath = null; private String fileBasePath = null; private int aspectX = 1; private int aspectY = 1; private int outputX = 480; private int outputY = 480; public TakePhoto(Activity activity, View displayView, TakePhotoListener takePhotoListener) { this.mActivity = activity; this.mDisplayView = displayView; this.mTakePhotoListener = takePhotoListener; initLocalFilePath(mActivity); startSelectImage(); } public TakePhoto(Activity activity, View displayView, int aspectX, int aspectY, int outputX, int outputY, TakePhotoListener takePhotoListener) { this.mActivity = activity; this.mDisplayView = displayView; this.aspectX = aspectX; this.aspectY = aspectY; this.outputX = outputX; this.outputY = outputY; this.mTakePhotoListener = takePhotoListener; initLocalFilePath(mActivity); startSelectImage(); } private void initLocalFilePath(Activity activity) { sdcardPath = activity.getExternalCacheDir().toString() + "/capturePicture/"; fileBasePath = "file://" + sdcardPath; } public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case PHOTO_REQUEST_CUT: try { setDisplayViewImage(); } catch (FileNotFoundException e) { mTakePhotoListener.onFail(TakePhotoFailReason.FileNotFound); } catch (OutOfMemoryError e) { mTakePhotoListener.onFail(TakePhotoFailReason.OutOfMemory); } break; } } protected void startSelectImage() { } protected Uri getCurrentUri() { Date date = new Date(System.currentTimeMillis()); SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss"); Log.i("------currentImageUri--------", fileBasePath + dateFormat.format(date) + ".jpg"); return Uri.parse(fileBasePath + dateFormat.format(date) + ".jpg"); } protected void cropImageUri(Uri uri) { try { // ���òü� mIntent.putExtra("crop", "true"); // aspectX aspectY �ǿ�ߵı��� mIntent.putExtra("aspectX", aspectX); mIntent.putExtra("aspectY", aspectY); // outputX outputY �Dzü�ͼƬ��� mIntent.putExtra("outputX", outputX); mIntent.putExtra("outputY", outputY); mIntent.putExtra("scale", true); mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); mIntent.putExtra("return-data", false); mIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); mIntent.putExtra("noFaceDetection", true); // no face detection mActivity.startActivityForResult(mIntent, PHOTO_REQUEST_CUT); } catch (ActivityNotFoundException e) { mTakePhotoListener.onFail(TakePhotoFailReason.ActivityNotFound); } } protected void setDisplayViewImage() throws FileNotFoundException { if (currentUri != null) { Bitmap bitmap = BitmapFactory.decodeFile(currentUri.getPath()); if (bitmap == null) { throw new FileNotFoundException(); } if (mDisplayView instanceof ImageView) { ((ImageView) mDisplayView).setImageBitmap(bitmap); } else { Drawable drawable = new BitmapDrawable(mActivity.getResources(), bitmap); mDisplayView.setBackgroundDrawable(drawable); } mTakePhotoListener.onSuccess(currentUri.getPath(), mDisplayView, bitmap); } } protected boolean existSDCard() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { return true; } else return false; } protected void createPhotoDir() { File file = new File(sdcardPath); if (!file.exists()) { file.mkdirs(); } } public interface TakePhotoListener { public void onSuccess(String imagePath, View displayView, Bitmap bitmap); public void onFail(TakePhotoFailReason failReason); } public enum TakePhotoFailReason { ActivityNotFound, FileNotFound, OutOfMemory, SDCardNotFound } }
//TakePhoto子类,实现从相机拍照生成图片 package com.focustech.capturepicture; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.provider.MediaStore; import android.view.View; public class CameraTakePhoto extends TakePhoto { /** * 构造方法 * @param activity 页面对象 * @param displayView 图片显示对象 * @param takePhotoListener 图片回调 */ public CameraTakePhoto(Activity activity, View displayView, TakePhotoListener takePhotoListener) { super(activity, displayView, takePhotoListener); } /** * 构造方法 * @param activity 页面对象 * @param displayView 图片显示对象 * @param aspectX 裁剪宽比例 * @param aspectY 裁剪高比例 * @param outputX 裁剪宽度 * @param outputY 裁剪高度 * @param takePhotoListener 图片回调 */ public CameraTakePhoto(Activity activity, View displayView, int aspectX, int aspectY, int outputX, int outputY, TakePhotoListener takePhotoListener) { super(activity, displayView, aspectX, aspectY, outputX, outputY, takePhotoListener); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { return; } super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case PHOTO_REQUEST_TAKEPHOTO: cropCurrentImage(currentUri); break; } } private void cropCurrentImage(Uri currentUri) { mIntent = new Intent("com.android.camera.action.CROP"); mIntent.setDataAndType(currentUri, "image/*"); cropImageUri(currentUri); } @Override protected void startSelectImage() { try { if (existSDCard()) { createPhotoDir(); currentUri = getCurrentUri(); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, currentUri); mActivity.startActivityForResult(intent, PHOTO_REQUEST_TAKEPHOTO); } else { mTakePhotoListener.onFail(TakePhotoFailReason.SDCardNotFound); } } catch (ActivityNotFoundException e) { mTakePhotoListener.onFail(TakePhotoFailReason.ActivityNotFound); } } } //TakePhoto子类,实现从本地图册中选择图片 public class GalleryTakePhoto extends TakePhoto { /** * 构造方法 * @param activity 页面对象 * @param displayView 图片显示对象 * @param takePhotoListener 图片回调 */ public GalleryTakePhoto(Activity activity, View displayView, TakePhotoListener takePhotoListener) { super(activity, displayView, takePhotoListener); } /** * 构造方法 * @param activity 页面对象 * @param displayView 图片显示对象 * @param aspectX 裁剪宽比例 * @param aspectY 裁剪高比例 * @param outputX 裁剪宽度 * @param outputY 裁剪高度 * @param takePhotoListener 图片回调 */ public GalleryTakePhoto(Activity activity, View displayView, int aspectX, int aspectY, int outputX, int outputY, TakePhotoListener takePhotoListener) { super(activity, displayView, aspectX, aspectY, outputX, outputY, takePhotoListener); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { return; } super.onActivityResult(requestCode, resultCode, data); } @Override protected void startSelectImage() { if (existSDCard()) { createPhotoDir(); currentUri = getCurrentUri(); mIntent = new Intent(Intent.ACTION_GET_CONTENT); mIntent.setType("image/*"); cropImageUri(currentUri); } else { mTakePhotoListener.onFail(TakePhotoFailReason.SDCardNotFound); } } }测试Activity...
package com.focustech.capturepicture; import android.app.Activity; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Bitmap; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.RelativeLayout; import com.focustech.capturepicture.TakePhoto.TakePhotoFailReason; import com.focustech.capturepicture.TakePhoto.TakePhotoListener; public class TestActivity extends Activity implements OnClickListener { private RelativeLayout img_btn; private Button btn1; private Button btn2; private TakePhoto takePhoto; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } // ��ʼ���ؼ� private void init() { img_btn = (RelativeLayout) findViewById(R.id.img_btn); btn1 = (Button) findViewById(R.id.btn1); btn2 = (Button) findViewById(R.id.btn2); // ΪImageButton��Button��Ӽ����¼� btn1.setOnClickListener(this); btn2.setOnClickListener(this); } // ����¼� @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: // ������õ�Activity,��ʾ�ؼ�����,��ȡͼƬ�ص� takePhoto = new CameraTakePhoto(this, img_btn, listener); break; case R.id.btn2: takePhoto = new GalleryTakePhoto(this, img_btn, listener); break; } } private TakePhotoListener listener = new TakePhotoListener() { @Override public void onSuccess(String imagePath, View displayView, Bitmap bitmap) { //���ݴ���Ŀؼ�ID���� switch (displayView.getId()) { case R.id.img_btn: Log.e("==========onSuccess=============", imagePath); break; } } @Override public void onFail(TakePhotoFailReason failReason) { Log.e("=======onFail===========", failReason.toString()); } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (takePhoto != null) { takePhoto.onActivityResult(requestCode, resultCode, data); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } }思路:其实功能是没有什么复杂的,就是调用系统功能去实现自己想要的功能,主要想表达的一点就是组件化的编程,好处是非常之多的,只要一次编写,以后就可以直接拿来用了,也正是体现了Java封装的强大之处.组件整个工程上传到了我的资源里,有需要的请下载。
相关文章推荐
- Android之圆形头像(实现相机拍摄+相册选择+图片裁剪功能)
- Android之圆形头像(实现相机拍摄+相册选择+图片裁剪功能)
- Android中相机拍摄照片,以及相册选择图片压缩上传(压缩后保存进SD中)(可用于修改头像等)
- Android实现相机拍摄、选择、图片裁剪功能
- Cocos2d-x 3.x 头像选择,本地相册图片+图片编辑(Android、IOS双平台)
- Android设置头像,手机拍照或从本地相册选取图片作为头像
- Android调用系统相册和相机选择图片并显示在imageview中
- Android多媒体之调用摄像头和从本地相册中选择图片
- android打开相册选取图片或打开相机拍照并进行裁剪
- Android 中打开相册图片 使用相机拍摄并存储照片
- Android 从相册和相机选取图片并剪切
- Android 拍照或从本地相册选取图片
- android 客户端通过选择本地相册和拍照上传本地图片到服务器端
- Android 相机或相册选择图片裁剪
- Android调用相机或选择相册后加载图片内存不足
- Android实现拍照,以及从相册选择图片裁剪功能同时保存在本地
- Android从相机、相册选择图片并裁剪
- android 开启本地相册选择图片并返回显示
- Android 使用系统相机拍摄照片保存到本地并在系统相册中显示
- Android选取相机、相册图片进行裁剪,并更新UI