前段时间,一直想写一个关于android相机的程序,实现如下功能:程序通过摄像机实时获取图像,但是不直接显示获取的图像,而是显示处理过后的图像。

就这个如何不显示处理前只显示处理后的图像,纠结了很久,网上搜索了很多,对于这个问题,网上的信息都是重复无用的,根本无法解决。接下来我详细的说明遇见的问题和解决方法。

一开始程序见程序段1,这么写的话,屏幕上面只会显示摄像头获取到的图片,处理过后的图片完全不会显示,后面要是强行的向这个surfaceholder控制的surfaceview来输出图片,程序会报错。

public void surfaceCreated(SurfaceHolder holder) {//开启相机camera=Camera.open();try{camera.setPreviewDisplay(surfaceholder);ShowMessage("开启相机成功");//toast提示}catch(Exception e){ShowMessage("开启相机失败");//toast提示camera.release();camera=null;}}//程序段1
后来发现可能是camera.setPreviewDisplay(surfaceholder)这句有问题,相机一直在用这个holder像surfaceview输出图像,后面程序中再使用surfaceholder来绘制新的图片,就会冲突,然后报错。

也试过用两个重叠的surfaceview来实现,一个给相机用,一个给处理后的图片用,通过程序控制将其中给相机用的那个隐藏掉,但是这么做行不通,后面再说为什么不行。也尝试过camera.setPreviewDisplay(null);这么写的话,在模拟器中是可以运行的,但是到了真机上面就不行了。在真机上,这两种办法都不会调用 onPreviewFrame(byte[] data, Camera arg1) ,查资料发现,android的相机获取的图片必须有一个surfaceview来显示,否则就不会调用 onPreviewFrame(byte[] data, Camera arg1) 方法。看到这里都会都会觉得Android好神烦。

在较新的apk版本中可以用camera.setPreviewTexture(surfacetexture)来替代camera.setPreviewDisplay(surfaceholder)。camera.setPreviewTexture(surfacetexture)这个方法允许相机获取的图片在一个隐藏的surfacetexture上显示,这么一来,便可以实现一开始提到的那个功能。

下面是一个基本的框架:

package com.example.atest01;import java.io.ByteArrayOutputStream;import java.io.IOException;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ImageFormat;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.SurfaceTexture;import android.graphics.YuvImage;import android.graphics.drawable.BitmapDrawable;import android.hardware.Camera;import android.hardware.Camera.PreviewCallback;import android.os.Bundle;import android.app.Activity;import android.util.DisplayMetrics;import android.view.Display;import android.view.Menu;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.Toast;public class MainActivity extends Activity implements SurfaceHolder.Callback {SurfaceHolder surfaceholder;SurfaceView surfaceview;Canvas canvas;Camera camera;SurfaceTexture surfacetexture;int counter=0;int width,height,sum;Bitmap img1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.activity_main);img1=((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap();surfaceview=(SurfaceView)findViewById(R.id.sv1);//获得控件  添加surfaceholdersurfaceholder=surfaceview.getHolder();surfaceholder.addCallback(this);surfacetexture=new SurfaceTexture(10);//surfaceholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//获得屏幕的长宽像素点数,这边的长宽像素要修改,不然会报错,//因为有的机型的长宽像素点数,不是setpreviewSize支持的长宽。DisplayMetrics dm=new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);width=dm.widthPixels;height=dm.heightPixels;sum=width*height;/*/显示屏幕的长宽像素点数String s=Integer.toString(width)+"\n"+Integer.toString(height);ShowMessage(s);//*/}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}public void ShowMessage(String text){Toast.makeText(this, text, Toast.LENGTH_SHORT).show();}@Overridepublic void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {Camera.Parameters parameters=camera.getParameters();parameters.setPictureSize(width, height);parameters.setPreviewSize(width, height);previewcallback pre = new previewcallback();//建立预览回调对象camera.setPreviewCallback(pre);        //camera.setPreviewCallback(pre); //设置预览回调对象camera.setParameters(parameters);camera.startPreview();ShowMessage("开启相机成功22323");counter++;ShowMessage(Integer.toString(counter));}@Overridepublic void surfaceCreated(SurfaceHolder holder) {//开启相机camera=Camera.open();try{camera.setPreviewTexture(surfacetexture);ShowMessage("开启相机成功");}catch(Exception e){ShowMessage("开启相机失败");camera.release();camera=null;}}@Overridepublic void surfaceDestroyed(SurfaceHolder arg0) {camera.stopPreview();camera.release();camera=null;}class previewcallback implements Camera.PreviewCallback{byte tmp;public previewcallback(){}@Overridepublic void onPreviewFrame(byte[] data, Camera arg1) {// TODO Auto-generated method stub//ShowMessage("开启相机成功qwe");try{ShowMessage("here go");}catch(Exception e){ShowMessage("Err 001");e.printStackTrace();}//*///此代码显示出每次都在调用这个onPreviewFrame方法}}}


更多相关文章

  1. Android性能优化之系统显示原理
  2. Android开发者选项中,这29个功能你忽略了吗?
  3. Android中新建的文件在R没有显示对应的文件解决办法总结
  4. TextView在显示文字的时候有个问题就是一行还没显示满就跳到下一
  5. Min3D测试-在Android里面载入MMD模型-快速3D模型显示测试-By黑月
  6. Android中使用Notification并通过点击Notification启动启动通知
  7. Android刘海屏、水滴屏全面屏最佳适配方案
  8. android/ophone 横竖屏切换问题的解决方案
  9. 不同手机在豌豆夹上显示设备同名的解决方法 && Android(安卓)获

随机推荐

  1. android 百度地图3.0+常用操作
  2. 怎么去掉联系人、通话记录、拨号列表界面
  3. Android系统下如何在程序中对XML里面元素
  4. Android(安卓)读取资源文件实例详解
  5. APK_获取Android的APK包签名信息
  6. Android(安卓)屏幕设置
  7. Android开源图表库介绍
  8. android启动后根文件系统分析
  9. 利用Handler来更新android的UI
  10. Android通过ContentProvider传输文件