Android之从Camera捕获图像讲解

我们知道所有带有摄像头的设备都会附带Camera应用程序,Camera 应用程序包含一个意图过滤器,用于与Camera

应用程序图像的获取。

为了通过一个意图利用Camera应用程序,我们需要构造一个意图过滤器,可以这样定义:

 

Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");


但在实际开发中,并不推荐这样做,这时我们可以指定MediaStore类中的常量ACTION_IMAGE_CAPTURE,使用这样

 

的好处是为了有利于未来的变化。因此,我们这样定义:

 

Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);


为了从Camera应用程序中获取图像,这时,应该将startActivity更改为startActivityForResult方法:

 

 

startActivityForResult(intent, 0);


这时我们从onActivityResult方法中获取返回的数据:

 

 

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode==RESULT_OK){	
			Bundle extras=data.getExtras();
			Bitmap bitmap=(Bitmap)extras.get("data");
		}
	}


Camera应用程序通过一个意图传递的附加值(extra)中返回图像,该意图将在onActivityRsult方法中传递给主调活

 

动。附加值的名称为“data”,它包含一个Bitmap对象,需要从泛型对象将它强制转换过来。

以上所得到的只是一个很小的图像,好吧,这其实得到的就是一个缩略图。

 

以上只是得到一个很小的缩略图,那如何获取大图的,在Android1.5开始,在大多数设备上可以将一个附加值传递给

触发Camera应用程序的意图,这个附加值的名称在MediaStore类中指定,它是一个常量,称为EXTRA_OUTPUT。

这个附加值用于指示Camera应用程序将捕获到的图像存放在什么位置。例如以下代码:

 

</pre><pre name="code" class="java">	String	mFilePath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/bill.jap";
		File file=new File(mFilePath);
		mImageUri=Uri.fromFile(file);
		
		Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
		intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageUri);
		startActivityForResult(intent, 0);

 

 

 

 

 

加载并显示一幅图像对内存使用情况很有影响,幸好Android提供了一个名为BitmapFactory的实用程序类,该程序类

提供了一系列的静态方法,允许通过各种来源加载Bitmap图像。BitmapFactory中的可用方法将会调用

BitmapFactory.Options类,这使得我们能够定义如何将Bitmap读入内存中。当加载图像时,可以设置BitmapFactory

使用的采样大小,在BitmapFactory.Options中指定inSampleSize参数。比如:

 

BitmapFactory.Options option=new BitmapFactory.Options();
		option.inSampleSize=5;
		Bitmap bitmap=BitmapFactory.decodeFile(mFilePath, option);


以上是将会产生一副大小是原始图像大小1/5的图像。

 

 

这是一种加速加载大图像的方法,但是没有真正考虑图像的原始大小,也没有考虑屏幕的大小,以下是获取屏幕的尺

寸:

 

DisplayMetrics metrics=new DisplayMetrics();
		this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		mWindowHeight=metrics.heightPixels;
		mWindowWidth=metrics.widthPixels;


为了确定图像的所有尺寸,我们使用了BitmapFactory和BitmapFactory.Options,并将

 

BitmapFactory.Options.inJustDecodeBounds变量设置为true。这将通知BitmapFactory类只返回该图像的范围,无须

尝试解码图像本身。当使用这个方法时,BitmapFactory.Options.outHeight和BitmapFactory.Options.outWidth变量将

会被赋值,例如:

 

 

BitmapFactory.Options mBitmapFactory=new BitmapFactory.Options();
			mBitmapFactory.inJustDecodeBounds=true;
			Bitmap bitmap=BitmapFactory.decodeFile(mFilePath, mBitmapFactory);
			int heightRatio=(int)Math.ceil(mBitmapFactory.outHeight/(float)mWindowHeight);
			int widthRatio=(int)Math.ceil(mBitmapFactory.outWidth/(float)mWindowWidth);


之后可以通过高度比率或宽度比率来显示图像大小。

 

 

以下是一个完整的示例代码:

 

MainActivity:

 

public class MainActivity extends Activity {
	
	private ImageView iv_show;
	private Button btn_open;
	
	private Uri mImageUri;
	
	private String mFilePath;
	
	private int mWindowWidth;
	private int mWindowHeight;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initEvent();
		initdata();
		
	}
	
	private void initdata(){
		
		
		
		mFilePath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/bill.jap";
		File file=new File(mFilePath);
		mImageUri=Uri.fromFile(file);
		
		DisplayMetrics metrics=new DisplayMetrics();
		this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		mWindowHeight=metrics.heightPixels;
		mWindowWidth=metrics.widthPixels;
	}
	
	private void initEvent(){

		btn_open.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
				intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageUri);
				startActivityForResult(intent, 0);
			}
		});
	}
	
	private void initView(){
		iv_show=(ImageView)findViewById(R.id.iv_show);
		btn_open=(Button)findViewById(R.id.btn_open);
	}


	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode==RESULT_OK){
			/*
			 * 加载图像尺寸
			 */
			BitmapFactory.Options mBitmapFactory=new BitmapFactory.Options();
			mBitmapFactory.inJustDecodeBounds=true;
			Bitmap bitmap=BitmapFactory.decodeFile(mFilePath, mBitmapFactory);
			int heightRatio=(int)Math.ceil(mBitmapFactory.outHeight/(float)mWindowHeight);
			int widthRatio=(int)Math.ceil(mBitmapFactory.outWidth/(float)mWindowWidth);
			
			/*
			 * 判断图像是否超出屏幕
			 */
			if(heightRatio>1&&widthRatio>1){
				if(heightRatio>1){
					mBitmapFactory.inSampleSize=heightRatio;
				}else{
					mBitmapFactory.inSampleSize=widthRatio;
				}
				
			}
			
			
			/*
			 * 进行解码
			 */
			mBitmapFactory.inJustDecodeBounds=false;
			bitmap=BitmapFactory.decodeFile(mFilePath, mBitmapFactory);
			
			iv_show.setImageBitmap(bitmap);
		}
	}
	
}


布局文件(activity_main):

 

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >

            <Button
                android:id="@+id/btn_open"
                android:layout_width="fill_parent"
                android:layout_height="50dp"
                android:text="Open" />

            <ImageView
                android:id="@+id/iv_show"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

</RelativeLayout>

 

 

 

 

 

 

最后别忘了给AndroidManifest添加相应的权限:

 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

 

 

 

 

 

转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/45696873情绪控_

 

 

©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:上身试试 返回首页