###这是个从相册或者相机获取图片的小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
学会简单的思想方式避免问题的复杂化。减少复杂代码,那么以后的问题和繁琐的过程就会少很多。