Android中实现拍照有两种方法,一种是调用系统自带的相机,然后使用其返回的照片数据。 还有一种是自己用Camera类和其他相关类实现相机功能,这种方法定制度比较高,洗染也比较复杂,这里我分别对这俩种方法进行了一顶的总结。
首先拿自己设定照相机这种方法来说,这个使用具有一定的局限性,因为有的现在手机设计样式不想以前那样,有个照相按钮,现在大部分都是设置在固定桌面进行拍照,所以使用受限,但在一定场合下还是可用的,下面就是先关代码:
首先我们还是先配置我们的AndroidManifest.xml文件 因为我们要访问照相机 和 SD卡对照片进行保存所以设置权限设置下面的语句:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
然后,我们应该对我们照相的界面进行配置 下面就是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" >
<SurfaceView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/surface" />
</LinearLayout>
因为我们知道我们在做视屏播放器的时候也是用到的SurfaceView,这里也是用到其设置。要注意宽和高我们均设置全充满,不然效果不佳。
为了我们照相机效果更加完美,我们应该先将标题和状态栏去掉。下面开始我们的主程序代码,
public class MainActivity extends Activity {
private boolean preview;
private SurfaceView surfaceView;
private Camera camera;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去除title
requestWindowFeature(Window.FEATURE_NO_TITLE);
//去掉Activity上面的状态栏
getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,
WindowManager.LayoutParams. FLAG_FULLSCREEN);
//设置亮度
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.main);
surfaceView=(SurfaceView)this.findViewById(R.id.surface);
//设置分辨率
surfaceView.getHolder().setFixedSize(960, 640);
//下面主要是手机自身引擎将得到的画面输出
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().addCallback(new SurfaceCallback());
}
相关说明一下我们先要对我们的想要的照相机的界面进行相关的设置操作作为准备工作,所以设置一些基本硬件设置!而且我们在做照相机最重要的应用就是回调的应用!
private final class SurfaceCallback implements SurfaceHolder.Callback{
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
// TODO Auto-generated method stub
try
{
camera=Camera.open();
//从窗口管理器中得到屏幕
WindowManager windowManager=(WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display display=windowManager.getDefaultDisplay();
//得到屏幕之后开始设置先关参数
Camera.Parameters parameters=camera.getParameters();
//得到预览图片的大小即为屏幕的尺寸 parameters.setPreviewSize(display.getWidth(),display.getHeight());
//设置每秒的帧数
parameters.setPreviewFrameRate(3);
//设置照片的输出格式
parameters.setPictureFormat(PixelFormat.JPEG);
//设置其照片的质量
parameters.set("jpeg-quality", 85);
//设置照片的大小
parameters.setPictureSize(display.getWidth(),display.getHeight());
camera.setParameters(parameters);
//通过surfaceView显示取景画面
camera.setPreviewDisplay(surfaceView.getHolder());
//开始预览
camera.startPreview();
preview=true;
} catch (IOException e)
{
// TODO Auto-generated catch block
System.out.print(e.toString());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
// TODO Auto-generated method stub
if (camera!=null)
{
if(preview)
{
camera.stopPreview();
camera.release();
}
}
}
}
//按键处理
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
// TODO Auto-generated method stub
//单次处理 并且不为空
if (camera!=null&&event.getRepeatCount()==0)
{
switch (keyCode)
{
//自动对焦
case KeyEvent.KEYCODE_SEARCH:
camera.autoFocus(null);
break;
//照相处理
case KeyEvent.KEYCODE_CAMERA:
case KeyEvent.KEYCODE_DPAD_CENTER:
//自动调用下面的照相类进行处理
//照相的时候为内部处理 调用硬件实现 所以无法为大家呈现预览功能
camera.takePicture(null,null, new TakePicture());
//此时硬件正在处理图片 此刻无法进行预览 必须在下面进行预览
break;
default:
break;
}
}
return true;
}
下面就是当我们照完相的时候我们定要为我们的相片进行保存,这里默认保存的路径为SD卡,而且当我们照完相的时候定要想做下次照相的预览功能,所以我们应该将预览功能放在之后做,下面就是实现过程:
//内部类进行照相处理
private final class TakePicture implements PictureCallback
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
// TODO Auto-generated method stub
//生成一张图片 并保存在SD卡上
try
{
Bitmap bitMap=BitmapFactory.decodeByteArray(data, 0, data.length);
File file=new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
FileOutputStream outputStream=new FileOutputStream(file);
bitMap.compress(CompressFormat.JPEG,100 , outputStream);
outputStream.close();
//照完一张图片之后可以继续进行预览照相
camera.stopPreview();
camera.startPreview();
} catch (Exception e)
{
// TODO Auto-generated catch block
System.out.println(e.toString());
}
}
}
}
总体来说这种方法起自己感觉有时不是太合适,收到限制,所以要我选择的话我会选择调用自己手机里的照相机!在测试这个工程的时候我也是用别人老一代的安卓测试用的,新一代的onKeyDown不知如何让使用!先要看自动调用系统的请看我下一篇的文章!