android之camera用法实例详解
本文实例讲述了android之camera用法。分享给大家供大家参考。具体如下:
1.关于预览横竖差90度的问题
原因分析
经过查证和实验,可以证实:android提供的sdk(android.hardware.camera)里大概不能正常的使用竖屏(portrait layout)加载照相机,当用竖屏模式加载照相机时会产生以下情况:
①. 照相机成像左倾90度(倾斜);
②. 照相机成像长宽比例不对(失比)。
之所以是“大概”,原因是因为可能可以通过一些比较复杂的手段解决。如果以上成立,那为什么竖屏不能正常成像也就很显然了。为什么会产生这样的情况,请看下面的研究分析。
照相机在一般情况下是必须用landscape layout(横屏)的,可以证明,先写一个照相机(只要能preview就行),如果manifest的activity里不加入android:screenorientation="landscape",即默认了 android:screenorientation="portrait"(竖屏),照相机preview时就会出现左倾90度的现象,并且失比。原因是这样的(我推测的),摄像头对照物的映射是android底层固定了的,以landscape方式为正,并且产生大小为320*480的像,如果换成portrait方式了,摄像头还是产生320*480的像,然后分别对应的放入到一个480*320的屏内,显然会失比,然后根据竖、横屏的规则,就产生了左倾90度的情况。为了进一步证实我对失比原因的推测,我照相机内加载的surfaceview调成了320*213,比例大概是(320:213)*1.5=(480:320),所成像结果如愿的形成左倾但是没有失比的状况,这就证实了我的想法。
综上可以看出,左倾是因为摄像头映射产生的,而失比是由于像素比例映射产生的。
解决方案
暂无好的解决方案,只能强制横屏,记载代码中加入
暂无好的解决方案,只能强制横屏,记载代码中加入
2.关于拍出来的照片不能正确成像,如绿屏,红绿相间,重叠等
原因分析
有的手机不支持parameter.setpicturesize(width,height)、parameters.setpreviewsize(width,height)方法,为了兼容性建议不设置这两个方法。
附:完整示例代码:
main.xml布局文件:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:layout_weight="2"> <surfaceview android:id="@+id/surfaceview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </linearlayout> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_weight="1" android:background="@android:color/white" android:layout_gravity="center"> <imagebutton android:layout_width="fill_parent" android:layout_height="80dip" android:id="@+id/btntakepicture" android:layout_gravity="center" android:textsize="30dip" android:layout_weight="1" android:src="@drawable/btn_take_pic"/> <imagebutton android:layout_width="fill_parent" android:layout_height="80dip" android:id="@+id/btnautofocus" android:layout_gravity="center" android:textsize="30dip" android:layout_weight="1" android:src="@drawable/btn_auto_focus"/> </linearlayout> </linearlayout>
二、mainactivity拍照核心代码:
package cn.itcast.takepicture; import java.io.file; import java.io.fileoutputstream; import android.app.activity; import android.content.pm.activityinfo; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.matrix; import android.graphics.pixelformat; import android.graphics.bitmap.compressformat; import android.hardware.camera; import android.hardware.camera.picturecallback; import android.os.bundle; import android.os.environment; import android.view.surfaceholder; import android.view.surfaceview; import android.view.view; import android.view.window; import android.view.windowmanager; import android.view.surfaceholder.callback; import android.widget.imagebutton; public class mainactivity extends activity { private imagebutton btntakepicture = null; private imagebutton btnautofocus = null; private camera camera = null; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // 设置窗口标题 requestwindowfeature(window.feature_no_title); // 横屏 setrequestedorientation(activityinfo.screen_orientation_landscape); // 全屏显示 getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, windowmanager.layoutparams.flag_fullscreen); // 当此窗口为用户可见时,保持设备常开,并保持亮度不变。 getwindow().addflags(windowmanager.layoutparams.flag_keep_screen_on); setcontentview(r.layout.main); surfaceview surfaceview = (surfaceview) this .findviewbyid(r.id.surfaceview); surfaceview.getholder() .settype(surfaceholder.surface_type_push_buffers); surfaceview.getholder().setfixedsize(320, 240); // 设置分辨率 surfaceview.getholder().addcallback(new surfacecallback()); btntakepicture = (imagebutton) findviewbyid(r.id.btntakepicture); btnautofocus = (imagebutton) findviewbyid(r.id.btnautofocus); btntakepicture.setonclicklistener(onclicklistener); btnautofocus.setonclicklistener(onclicklistener); } private final view.onclicklistener onclicklistener = new view.onclicklistener() { @override public void onclick(view v) { if (v == btntakepicture) { if (camera != null) camera.takepicture(null, null, new takepicturecallback()); // 拍照 } else if (v == btnautofocus) { if (camera != null) camera.autofocus(null); // 对焦 } } }; private final class surfacecallback implements callback { private boolean preview; // 是否正在预览 @override public void surfacechanged(surfaceholder holder, int format, int width, int height) { } @override public void surfacecreated(surfaceholder holder) { try { camera = camera.open(); camera.parameters parameters = camera.getparameters(); parameters.setpreviewframerate(5); //每秒5帧 parameters.setpictureformat(pixelformat.jpeg);//设置照片的输出格式 parameters.set("jpeg-quality", 85);//照片质量 camera.setparameters(parameters); camera.setpreviewdisplay(holder); camera.startpreview(); preview = true; } catch (exception e) { e.printstacktrace(); } } @override public void surfacedestroyed(surfaceholder holder) { if (camera != null) { if (preview) { camera.stoppreview(); preview = false; } camera.release(); camera = null; // 记得释放 } } } private final class takepicturecallback implements picturecallback { public void onpicturetaken(byte[] data, camera camera) { bitmap bitmap = bitmapfactory.decodebytearray(data, 0, data.length); matrix matrix=new matrix(); //设置缩放 matrix.postscale(0.5f, 0.5f); bitmap=bitmap.createbitmap(bitmap, 0, 0, bitmap.getwidth(), bitmap.getheight(), matrix, true); file file = new file(environment.getexternalstoragedirectory(), system.currenttimemillis() + ".jpg"); try { fileoutputstream outstream = new fileoutputstream(file); bitmap.compress(compressformat.jpeg, 100, outstream); outstream.close(); camera.startpreview(); } catch (exception e) { e.printstacktrace(); } } } }
清单文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.itcast.takepicture" android:versioncode="1" android:versionname="1.0" > <application android:icon="@drawable/icon" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".mainactivity" > <intent-filter > <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> <uses-sdk android:minsdkversion="7" /> <uses-permission android:name="android.permission.camera" /> <!-- 在sdcard中创建与删除文件权限 --> <uses-permission android:name="android.permission.mount_unmount_filesystems" /> <!-- 往sdcard写入数据权限 --> <uses-permission android:name="android.permission.write_external_storage" /> </manifest>
希望本文所述对大家的android程序设计有所帮助。