###这是个从相册或者相机获取图片的小demo
功能介绍: 1:拍照获取照片并且显示和保存在文件夹中
2: 相册中获取照片并且显示和保存在文件夹中

灵感来源: 发射多个intent

####涉及的知识点

1:bitmap 的使用
2:intent 的使用
3:BitmapFactory 的使用
4:BitmapFactory.Options 的理解
5:理解File FileOutputStream ByteArrayOutputStream 的使用
6:加载图片的内存处理

####全部代码

public class Test16 extends Activity {
	private String pathString = "/sdcard/myImage/";
	private String name = "/sdcard/myImage/";
	//或者 Environment.getDataDirectory()+"/myImage/";
	private final static String TAG = "Test16.class";
	private Button button;
	private ImageView imageView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test16);
		init();
		
	}

	private void init() {
		button = (Button) findViewById(R.id.button);
		imageView = (ImageView) findViewById(R.id.imageview);
		button.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent pickIntent = new Intent(Intent.ACTION_GET_CONTENT);
				pickIntent.setType("image/*");
				// 設置從content中获取的内容和格式

				Intent chooserIntent = Intent.createChooser(pickIntent, "全部");

				name = pathString + System.currentTimeMillis() + ".jpg";// 用时间戳
																		// 生成图片,那么图片就可以不重复
				File vFile = new File(name);
				if (!vFile.exists()) {
					vFile.getParentFile().mkdir();
				}// 判断当前目录有没有这个文件,没有则创建
				Uri uri = Uri.fromFile(vFile);
				// 把 file文件转换为uri 类型

				Intent takePhotoIntent = new Intent(
						MediaStore.ACTION_IMAGE_CAPTURE);
				// 设置意图为 照相机
				takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
				// 设置intent多种类型

				chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
						new Intent[] { takePhotoIntent });
				startActivityForResult(chooserIntent, 0);
			}
		});
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (data == null) {
			// 对相机处理
			try {
				if (!(new File(name).exists())) {
					return;
				}// 避免報錯
					// 在文件点击选择的时候,如果不选择,那么文件不存在,会报错 retrun可以避免报错
				Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
						new File(name)));
				// 从文件中获取图片,然后解析为bitmanp

				BitmapFactory.Options options = new Options();
				ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
				bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream);
				// 对图片压缩处理输出为 outputstream

				options.inJustDecodeBounds = true;// 设置true 不会返回图片

				// BitmapFactory.decodeStream(new ByteArrayInputStream(
				// outputStream.toByteArray()), null, options);
				BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0,
						outputStream.size(), options);
				// 解析图片bitmap,返回bitmap的长宽高
				options.inJustDecodeBounds = false;
				options.inSampleSize = simple(options, 100, 100);
				// 返回inSampleSize壓縮比例
				bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(
						outputStream.toByteArray()), null, options);
				
				File file = new File(name);
				FileOutputStream dFileOutputStream = new FileOutputStream(file);
				dFileOutputStream.write(outputStream.toByteArray(), 0,
						outputStream.size());
				dFileOutputStream.flush();
				dFileOutputStream.close();
				//保存可以正常显示的图片bitmap
				Log.w(TAG, "成功");
				imageView.setImageBitmap(bitmap);
			} catch (FileNotFoundException e) {
				Log.w(TAG, "找不到文件");
				e.printStackTrace();
			} catch (IOException e) {
				Log.w(TAG, "io报错");
				e.printStackTrace();
			}

		} else {// 對gallery的處理
			Uri uri = data.getData();
			try {
				Bitmap bitmap = MediaStore.Images.Media.getBitmap(
						this.getContentResolver(), uri);

				BitmapFactory.Options options = new Options();
				ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
				bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream);
				options.inJustDecodeBounds = true;// 设置true 不会返回图片

				// BitmapFactory.decodeStream(new ByteArrayInputStream(
				// outputStream.toByteArray()), null, options);

				BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0,
						outputStream.size(), options);

				options.inSampleSize = simple(options, 100, 100);

				options.inJustDecodeBounds = false;
				Log.w(TAG, "inSampleSize 大小为" + options.inSampleSize
						+ "  outHeight" + options.outHeight + "  " + "outWidth"
						+ options.outWidth);

				// bitmap = BitmapFactory
				// .decodeStream(
				// new ByteArrayInputStream(outputStream
				// .toByteArray()), null, options);

				bitmap = BitmapFactory.decodeByteArray(
						outputStream.toByteArray(), 0, outputStream.size(),
						options);

				if (bitmap != null) {

					bitmap.compress(CompressFormat.PNG, 50, outputStream);

					imageView.setImageBitmap(bitmap);
					Log.w(TAG, "Bitmap2的ByteCount为: " + bitmap.getByteCount()
							+ "  ||");
					File file = new File(name);
					FileOutputStream dFileOutputStream = new FileOutputStream(
							file);

					dFileOutputStream.write(outputStream.toByteArray(), 0,
							outputStream.size());
					dFileOutputStream.flush();
					dFileOutputStream.close();
				}

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private int simple(BitmapFactory.Options options, int h, int w) {
		int i = 1;

		if (options.outHeight > h || options.outWidth > w) {

			int hh = options.outHeight / h;
			int ww = options.outWidth / w;
			if (hh > ww) {
				i = ww;
			} else {
				i = hh;
			}
			if (i > 8) {
				i = 8;
			}
		}

		// 另外一套代码 保存为800 左右
		// i = 1;
		// if (options.outHeight > 1000 || options.outWidth > 1000) {
		// int hhh = options.outHeight / 1000;
		// int www = options.outWidth / 1000;
		// if (hhh > www) {//保持像素1000左右
		// i = www;
		// } else {
		// i = hhh;
		// }
		// }

		return i;
	}

}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择照片" />

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

#####代码块分析
点击事件的代码
intent

Intent pickIntent = new Intent(Intent.ACTION_GET_CONTENT);
pickIntent.setType("image/*");
				// 設置從content中获取的内容和格式

Intent chooserIntent = Intent.createChooser(pickIntent, "全部");

name = pathString + System.currentTimeMillis() + ".jpg";// 用时间戳
																		// 生成图片,那么图片就可以不重复
File vFile = new File(name);
	if (!vFile.exists()) {
	vFile.getParentFile().mkdir();
	}// 判断当前目录有没有这个文件,没有则创建
	Uri uri = Uri.fromFile(vFile);
				// 把 file文件转换为uri 类型

Intent takePhotoIntent = new Intent(
						MediaStore.ACTION_IMAGE_CAPTURE);
	// 设置意图为 照相机
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
	// 设置intent多种类型

chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
			new Intent[] { takePhotoIntent });
startActivityForResult(chooserIntent, 0);

上面的代码块中,设置intent 意图,然后点击会有下面的效果。
在上述代码中,首先创建一个String ;类型保存 图片的路径和名字,然后判断路径存不存在,不存在新建一个文件夹。记得这类的操作需用权限。至于什么权限,你自己想吧……
file -> uri ,uri -> putExtra

预览:

处理相机的代码

下面的是对相机代码的处理。
首先,调用相机的时候,有一种调用方法是有返回data的,不过这个是缩略图。当用intenty一些参数设定后,会造成data为空,这个时候图片的路径在之前的uri上。
一开始获得的图片的数据类型是输入流,然后利用BitmapFactory 把输入流转换为 bitmap 获取bitmap 后,这个时候的bitmap 的宽度和高度 肯定很大。所以利用 BitmapFactory.Options 设置对图片的压缩比例。这里的压缩不是质量压缩。
理解 options.inJustDecodeBounds = true or false FileOutputStream 利用保存文件

if (data == null) {
			// 对相机处理
	try {
		if (!(new File(name).exists())) {
			return;
		}// 避免報錯
		// 在文件点击选择的时候,如果不选择,那么文件不存在,会报错 retrun可以避免报错
	Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
			new File(name)));
			// 从文件中获取图片,然后解析为bitmanp

	BitmapFactory.Options options = new Options();
	ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
	bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream);
	// 对图片压缩处理输出为 outputstream

	options.inJustDecodeBounds = true;// 设置true 不会返回图片

	// BitmapFactory.decodeStream(new ByteArrayInputStream(
	// outputStream.toByteArray()), null, options);
	BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0,
			outputStream.size(), options);
				// 解析图片bitmap,返回bitmap的长宽高
	options.inJustDecodeBounds = false;
	options.inSampleSize = simple(options, 100, 100);
				// 返回inSampleSize壓縮比例
	bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(
				outputStream.toByteArray()), null, options);
				
	File file = new File(name);//保存文件
	FileOutputStream dFileOutputStream = new FileOutputStream(file);
	dFileOutputStream.write(outputStream.toByteArray(), 0,
				outputStream.size());
	dFileOutputStream.flush();
	dFileOutputStream.close();
				//保存可以正常显示的图片bitmap
				Log.w(TAG, "成功");
	imageView.setImageBitmap(bitmap);
			} catch (FileNotFoundException e) {
				Log.w(TAG, "找不到文件");
				e.printStackTrace();
			} catch (IOException e) {
				Log.w(TAG, "io报错");
				e.printStackTrace();
			}

处理相册图片的代码

下面的代码是对从相册中获取照片的处理
上面的代码中从bitmap转换到ByteArrayOutputStream 是参考下面的代码。
uri 是从 getData中获取。但 String name 这个文件还是可以使用的。

else {// 對gallery的處理
	Uri uri = data.getData();
	try {
		Bitmap bitmap = MediaStore.Images.Media.getBitmap(
					this.getContentResolver(), uri);

		BitmapFactory.Options options = new Options();
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream);
		options.inJustDecodeBounds = true;// 设置true 不会返回图片

				// BitmapFactory.decodeStream(new ByteArrayInputStream(
				// outputStream.toByteArray()), null, options);

		BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0,
				outputStream.size(), options);

		options.inSampleSize = simple(options, 100, 100);

		options.inJustDecodeBounds = false;
		Log.w(TAG, "inSampleSize 大小为" + options.inSampleSize
				+ "  outHeight" + options.outHeight + "  " + "outWidth"
				+ options.outWidth);

				// bitmap = BitmapFactory
				// .decodeStream(
				// new ByteArrayInputStream(outputStream
				// .toByteArray()), null, options);

		bitmap = BitmapFactory.decodeByteArray(
				outputStream.toByteArray(), 0, outputStream.size(),
				options);

		if (bitmap != null) {

			bitmap.compress(CompressFormat.PNG, 50, outputStream);

			imageView.setImageBitmap(bitmap);
			Log.w(TAG, "Bitmap2的ByteCount为: " + bitmap.getByteCount()
							+ "  ||");
			File file = new File(name);
			FileOutputStream dFileOutputStream = new FileOutputStream(
					file);

			dFileOutputStream.write(outputStream.toByteArray(), 0,
					outputStream.size());
			dFileOutputStream.flush();
			dFileOutputStream.close();
		}

	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}
缩放bitmap代码

下面的代码 是 获取好的缩放比例
从思维惯性而言,好的缩放比例能更好的节约内存。
```java private int simple(BitmapFactory.Options options, int h, int w) { int i = 1;

if (options.outHeight > h || options.outWidth > w) {

	int hh = options.outHeight / h;
	int ww = options.outWidth / w;
	if (hh > ww) {
		i = ww;
	} else {
		i = hh;
	}
	if (i > 8) {
		i = 8;
	}
}

	// 另外一套代码 保存为800 左右
	// i = 1;
	// if (options.outHeight > 1000 || options.outWidth > 1000) {
	// int hhh = options.outHeight / 1000;
	// int www = options.outWidth / 1000;
	// if (hhh > www) {//保持像素1000左右
	// i = www;
	// } else {
	// i = hhh;
	// }
	// }

return i; } ```
相机图片的某些代码优化
	if (data==null) {
	try {
		if (!(new File(name).exists())) {
		return;
		}
	BitmapFactory.Options options = new Options();
	options.inJustDecodeBounds = true;
	BitmapFactory.decodeFile(name, options);
	options.inJustDecodeBounds = false;
	options.inSampleSize = simple(options, 100, 100);
	Bitmap bitmap = BitmapFactory.decodeFile(name, options);
	imageView.setImageBitmap(bitmap);
				
	} catch (Exception e) {
		}
}

上述的代码跟之前的有什么不同? 首先,在intent的时候,我们调用的是 takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 图片的保存输出到uri的地址上面。
uri 是由file 转换而来的,换言之,file记录了图片的地址
所以可直接测量图片的大小 而不返回图片。减少内存的使用。

Tag

学会简单的思想方式避免问题的复杂化。减少复杂代码,那么以后的问题和繁琐的过程就会少很多。