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