采集更大的图像
为了解决大小限制,从Android 1.5开始,在大多数机器上,我们传入一个extra到激活相机应用的Intent中。此extra的名字在MediaStore类中定义为EXTRA_OUTPUT。它的值(extra以名称-值对的形式存在)以URI的形式,为相机应用指定了拍摄的图像保存的地方。
下面的代码段要求相机应用将图像保存到设备的SD卡,文件名为myfavoritepicture.png。
String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/myfavoritepicture.jpg";
File imageFile = new File(imageFilePath);
Uri imageFileUri = Uri.fromFile(imageFile);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(i, CAMERA_RESULT); 注意:上述创建图像文件URI的代码段可以简化如下:
imageFileUri = Uri.parse("file:///sdcard/myfavoritepicture.jpg");
虽然在实践中,所示的方法设备无关性更强,而且当SD卡的命名规则或者URI的语法因本地系统改变时,仍然能够兼容。加载和显示图像涉及大量使用内存。例如,HTC G1手机拥有一个320万像素的摄像头。320M像素的摄像头,拍摄的图像通常为2048x1536像素。显示32位的这样大小的图像需要多达100663kb,大约13MB的内存。虽然不能肯定我们的应用就会耗尽内存,但是它显然使内存耗尽的可能性大大增加了。
Android给我们提供了一个名为BitmapFactory的工具类,它提供了一系列的静态方法从各种源加载位图图像。我们的需求是从文件加载图像,并把它显示在我们最初的activity中。幸运的是,BitmapFactory提供的加载方法都接受BitmapFactory.Options类,它允许我们定义将位图读入到内存的方式。具体来说,我们可以设置BitmapFactory加载图像的采样大小。指定BitmapFactory.Options类的inSampleSize参数,得到的位图图像将为原图大小inSampleSize分之一。例如,像我在这里做的,inSampleSize设置为8,将生成一个原图1/8大小的图像。
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inSampleSize = 8; Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); imv.setImageBitmap(bmp);
这是一个快速加载大图像的方法,但是没有考虑图像的原始大小以及屏幕的大小。如果我们缩放图像使之适应我们的屏幕,那就更好了。
下面的代码段说明了如何使用屏幕的大小确定加载图像时的采样值。当我们采用这些方法时,图像能够确保尽可能的填充屏幕。然而,如果图像的任一维度只显示100像素,则这个值将用来替换屏幕的维度。获取显示屏维度的代码如下:
Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight();
//加载图像的外形尺寸,而非图像本身
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);
Log.v("HEIGHTRATIO",""+heightRatio);
Log.v("WIDTHRATIO",""+widthRatio);
//如果两个比值都大于1,
//那么图像的某一边大于屏幕
if (heightRatio > 1 && widthRatio > 1) {
if (heightRatio > widthRatio) {
//高度比较大,以它进行缩小
bmpFactoryOptions.inSampleSize = heightRatio;
}
else {
//宽度比较大,以它进行缩小
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
// 真正解码图像
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
package com.apress.proandroidmedia.ch1.sizedcameraintent;
import java.io.File;
import android.app.Activity;
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.util.Log;
import android.view.Display;
import android.widget.ImageView;
public class SizedCameraIntent extends Activity {
final static int CAMERA_RESULT = 0;
ImageView imv; String imageFilePath;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/myfavoritepicture.jpg";
File imageFile = new File(imageFilePath);
Uri imageFileUri = Uri.fromFile(imageFile);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(i,CAMERA_RESULT);
}
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK) {
//取得ImageView的引用
imv = (ImageView) findViewById(R.id.ReturnedImageView);
Display currentDisplay = getWindowManager().getDefaultDisplay();
int dw = currentDisplay.getWidth();
int dh = currentDisplay.getHeight();
//加载图片的尺寸信息,而非图像本身
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);
Log.v("HEIGHTRATIO",""+heightRatio);
Log.v("WIDTHRATIO",""+widthRatio);
// 如果两个比值都大于1,
// 那么图像的某一边大于屏幕
if (heightRatio > 1 && widthRatio > 1) {
if (heightRatio > widthRatio) {
// 高度比较大,以它进行缩小
bmpFactoryOptions.inSampleSize = heightRatio;
}
else {
// 宽度比较大,以它进行缩小
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
// 真正解码图像
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
// 显示图像
imv.setImageBitmap(bmp);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:id="@+id/ReturnedImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
</LinearLayout>
Android多媒体开发 Pro Android Media 第一章 Android图像编程入门 2
原文:http://blog.csdn.net/dairyman000/article/details/19421767