从系统中取图片这个是写安卓非常常见的一个功能,但是很多时候我们每次我们都去写一个还是比较麻烦的。
下面我就介绍我写的一个已经封装好的一个类,先看截图
从截图上看,功能很清晰,点击获取图片按钮,出来一个半透明的界面,具有用相机拍照获取图片和从相册中选择两种途径去获取图片。
看完截图直接上代码
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
时间: 2024-12-29 11:28:45