如何让每一个500毫秒后摄像头preVIEW框架 [英] How to get camera preview frame after every 500ms

查看:285
本文介绍了如何让每一个500毫秒后摄像头preVIEW框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发的示例应用程序,让我色$ C $尖锐的图像或对象了C通过摄像头的机器人。我的应用是类似这样的应用程序,我使用申请code这一点。

使用此应用程序code,我能够不断地得到相机preVIEW框架,这让我的色彩$ C $当前previewframe℃。我想使它一些延迟。我希望每一个500毫秒后,得到的只有1个摄像头preVIEW框架。

如何才能做到这一点,我需要做的,这个code什么修改。

code:

 类preVIEW延伸SurfaceView实现SurfaceHolder.Callback,previewCallback {

    公共接口previewListener {
        公共无效在previewUpdated(INT []像素,诠释的宽度,高度INT);
    }

    previewListener监听;
    SurfaceHolder mHolder;
    相机mCamera = NULL;
    byte []的缓冲区;
    INT缓冲区大小;
    私人布尔isFrontCamera = FALSE;
    布尔lightOn = FALSE;

    私人布尔isPaused得到= FALSE;

    //这个变量是负责获取和设置的相机设置
    私人参数参数;
    //这个变量存储摄像机的preVIEW大小
    私人大小previewSize;
    //这个数组存储像素为十六进制对
    私人INT []像素;

    preVIEW(上下文的背景下){
        超(上下文);

        //安装SurfaceHolder.Callback所以我们得到通知时,该
        //下垫面创建和销毁。
        mHolder = getHolder();
        mHolder.addCallback(本);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        尝试 {
            //实例化EnterColorListener,所以我们可以将事件发送到主机
            监听=(previewListener)范围内;
        }赶上(ClassCastException异常E){
            //活动不实现接口,抛出异常
            抛出新ClassCastException异常(context.toString()
                    +必须实现previewListener);
        }
    }

    公共无效surfaceCreated(SurfaceHolder持有者){
        //表面经创建,获取摄像机,并告诉它在哪里
        //绘制。
        尝试 {
            CameraInfo信息=新CameraInfo();
            Camera.getCameraInfo(0,信息);
            如果(info.facing == CameraInfo.CAMERA_FACING_FRONT){
                this.isFrontCamera =真;
            }
            mCamera = Camera.open(0); //尝试获取的Camera实例。指数B / C前摄像头都OK了。

        }
        赶上(例外五){
            //相机无法使用(使用或不存在)
            Log.e(相机错误,无法打开相机);
            返回;
        }
        尝试 {
           mCamera.setDisplayOrientation(90);
           mCamera.set previewDisplay(保持器);
        }赶上(IOException异常除外){
            mCamera.release();
            mCamera = NULL;
        }
    }

    //感谢骗codeR @ github上
    公共无效闪光灯(){
        如果(supportsFlash()){
            如果(!lightOn){
                lightOn =真;
                mCamera.stop preVIEW();
                mCamera.set previewCallbackWithBuffer(本); // mCamera.set previewCallback(本); //设置previewCallbackWithBuffer(本);
                parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
                mCamera.setParameters(参数);
                mCamera.start preVIEW();
            } 其他 {
                lightOn = FALSE;
                mCamera.stop preVIEW();
                mCamera.set previewCallbackWithBuffer(本); //设置previewCallback(本); //设置previewCallbackWithBuffer(本);
                parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
                mCamera.setParameters(参数);
                mCamera.start preVIEW();
            }
        }
    }

    //感谢http://ikravchenko.blogspot.com/2013/09/nexus-7-2013-torch-issue.html
    公共布尔supportsFlash(){
         如果(的getContext()。getPackageManager()。hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
             参数= mCamera.getParameters();
             如果(parameters.getFlashMode()!= NULL){
                名单<字符串> supportedFlashModes = parameters.getSupportedFlashModes();
                 如果(supportedFlashModes ==空|| supportedFlashModes.isEmpty()|| supportedFlashModes.size()== 1&安培;&安培; supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)){
                     返回false;
                 }
                 返回true;
             }
         }
         返回false;
    }


    公共无效surfaceDestroyed(SurfaceHolder持有者){
        //面,当我们返回将被销毁,所以停止了preVIEW。
        //因为CameraDevice对象不是共享资源,这是非常
        //重要的是要释放它当活动被暂停。
        如果(mCamera!= NULL){
            mCamera.stop preVIEW();
            mCamera.set previewCallback(NULL); //设置previewCallbackWithBuffer(空);
            mCamera.release();
            mCamera = NULL;
        }
    }

    公共布尔isFrontCamera(){
        返回isFrontCamera;
    }

    / * TODO:修复bug的空指针异常* /
    公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
        //现在的尺寸是已知的,设置相机参数,并开始
        //在preVIEW。
        如果(mCamera!= NULL){
            参数= mCamera.getParameters();

            //做自动对焦,需要设置的参数(如果可用)
            //http://stackoverflow.com/questions/11623266/camera-parameters-setfocusmode-is-not-working
            名单<字符串> focusModes = parameters.getSupportedFocusModes();
            如果(focusModes!= NULL){
                如果(focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
                    parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                否则,如果(focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                    parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                否则,如果(focusModes.contains(Parameters.FOCUS_MODE_AUTO))
                    parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
            }

            //必须得到previewSizes因为不是所有的设备都支持任意的previews
            //下面是堆栈溢出
            INT宽度= this.getWidth();
            INT高= this.getHeight();
            大小最好= NULL;
            名单< Camera.Size> previewSizes = parameters.getSupported previewSizes();
            //你需要选择最合适的previewSize您的应用程序
            的for(int i = 0; I< previewSizes.size();我++){
                尺寸尺寸= previewSizes.get(我);
                如果((size.width< =宽度放大器;&安培; size.height< =身高)||(size.height< =宽度放大器;&安培; size.width< =身高)){
                    如果(最好== NULL){
                        最好=大小;
                    } 其他 {
                        INT resultArea = best.width * best.height;
                        INT newArea = size.width * size.height;

                        如果(newArea> resultArea){
                            最好=大小;
                        }
                   }
                }
            }

            //确保东西挑选出来的。 previewSizes保证为是至少有一件事。
            如果(最好的!= NULL){
                previewSize =最好;
            } 其他 {
                previewSize = previewSizes.get(0);
            }

            parameters.set previewSize(previewSize.width,previewSize.height);
            像素=新INT [previewSize.width * previewSize.height]。
            mCamera.setParameters(参数);

            //设置在这个类进行一个定义相机回调
            mCamera.set$p$pviewCallbackWithBuffer(this);//set$p$pviewCallback(this);//set$p$pviewCallbackWithBuffer(this);
            BUFFERSIZE = $p$pviewSize.width*$p$pviewSize.height*ImageFormat.getBitsPerPixel(parameters.get$p$pviewFormat())/8;
            缓冲区=新的字节[BUFFERSIZE]
            resetBuffer();

            (!isPaused得到),如果mCamera.start preVIEW();

        }
    }

    公共无效暂停(布尔isPaused得到){
        this.isPaused = isPaused得到;
        如果(isPaused得到){
            parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            mCamera.setParameters(参数);
            mCamera.stop preVIEW();
        } 其他 {
            如果(mCamera!= NULL){
                mCamera.set$p$pviewCallbackWithBuffer(this);//set$p$pviewCallback(this);//set$p$pviewCallbackWithBuffer(this);

                如果(lightOn)
                    parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);

                mCamera.setParameters(参数);
                mCamera.start preVIEW();
            }
        }
    }

    公共无效resetBuffer(){
        如果(mCamera!= NULL){
            mCamera.addCallbackBuffer(缓冲液);
        }
    }


    @覆盖
    在previewFrame(byte []的数据,摄像头摄像头){公共无效
        //变换NV21像素数据分成RGB像素
        德codeYUV420SP(像素,数据,previewSize.width,previewSize.height);
        listener.On previewUpdated(像素,previewSize.width,previewSize.height);
    }

    //从科泰项目的方法!不是我的!见下文...
    虚空德codeYUV420SP(INT [] RGB,byte []的yuv420sp,诠释的宽度,高度INT){

            最终诠释框架尺寸=宽*高;

            为(诠释J = 0,YP = 0; J&所述;高度; J ++){INT UVP =框架尺寸+(J>→1)*宽度,U = 0,V = 0;
              的for(int i = 0; I<宽度;我++,YP ++){
                INT Y =(0xFF的及((int)的yuv420sp [YP])) -  16;
                如果(γ℃的)
                  Y = 0;
                如果((ⅰ&安培; 1)== 0){
                  V =(0xFF的&放大器; yuv420sp [UVP ++]) -  128;
                  U =(0xFF的&放大器; yuv420sp [UVP ++]) -  128;
                }

                INT y1192 = 1192 * Y;
                INT R =(y1192 + 1634 * V);
                INT G =(y1192  -  833 * V  -  400 * U);
                INT B =(y1192 + 2066 * U);

                如果(为r 0)R = 0;否则,如果(R> 262143)
                   R = 262143;
                如果(克℃,)克= 0;否则,如果(G> 262143)
                   G = 262143;
                如果(b将0)B = 0;否则,如果(B> 262143)
                   B = 262143;

                RGB [YP] = 0xff000000 | ((为r&10 6)及为0xFF0000)| ((g取代;→2)及为0xFF00)| ((B个大于10)及0xff的);
              }
         }
    }

}
 

解决方案

您可以计算在previewFrame经过的时间()。例如:

 布尔isFirstTime = TRUE;
    长的startTime = 0;
    previewCallback回调=新的previewCallback(){
        @覆盖
        在previewFrame(byte []的数据,摄像头摄像头){公共无效
            // TODO自动生成方法存根
            如果(isFirstTime){
                isFirstTime = FALSE;
                的startTime = SystemClock.currentThreadTimeMillis();
                德codeYUV420SP(像素,数据,previewSize.width,previewSize.height);
                listener.On previewUpdated(像素,previewSize.width,previewSize.height);
            }
            其他 {
                长currentTime的= SystemClock.currentThreadTimeMillis();
                长ela​​psedTime = currentTime的 - 的startTime;
                如果(elapsedTime> = 500){//触发事件
                    的startTime = currentTime的;
                    德codeYUV420SP(像素,数据,previewSize.width,previewSize.height);
                    listener.On previewUpdated(像素,previewSize.width,previewSize.height);
                }
            }
        }
    };
 

不要忘了,当你切换preVIEW状态重置布尔值和开始时间。

I am developing sample application which gives me color code of pointed image or object via Camera in android. My application is similar to this application and I am using this application code for this.

Using this application code I am able to get camera preview frames continuously and it gives me color code of current previewframe. I want to make it some delay. I want to get only 1 camera preview frame after every 500ms.

How Can i do that, what modification I need to do in this code.

Code :

class Preview extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback { 

    public interface PreviewListener {
        public void OnPreviewUpdated(int[] pixels, int width, int height);
    }

    PreviewListener listener;
    SurfaceHolder mHolder;  
    Camera mCamera = null;  
    byte[] buffer;
    int bufferSize;
    private boolean isFrontCamera = false;
    boolean lightOn = false;

    private boolean isPaused = false;

    //This variable is responsible for getting and setting the camera settings  
    private Parameters parameters;  
    //this variable stores the camera preview size   
    private Size previewSize;  
    //this array stores the pixels as hexadecimal pairs   
    private int[] pixels;  

    Preview(Context context) {  
        super(context);  

        // Install a SurfaceHolder.Callback so we get notified when the  
        // underlying surface is created and destroyed.  
        mHolder = getHolder();  
        mHolder.addCallback(this);  
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  

        try {
            // Instantiate the EnterColorListener so we can send events to the host
            listener = (PreviewListener) context;
        } catch (ClassCastException e) {
            // The activity doesn't implement the interface, throw exception
            throw new ClassCastException(context.toString()
                    + " must implement PreviewListener");
        }
    }  

    public void surfaceCreated(SurfaceHolder holder) {  
        // The Surface has been created, acquire the camera and tell it where  
        // to draw.  
        try {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(0, info);
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                this.isFrontCamera = true;
            }
            mCamera = Camera.open(0); // attempt to get a Camera instance.  index b/c front cameras are ok too.

        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
            Log.e("camera error", "could not open camera");
            return;
        }
        try {  
           mCamera.setDisplayOrientation(90);
           mCamera.setPreviewDisplay(holder);  
        } catch (IOException exception) {  
            mCamera.release();  
            mCamera = null;  
        }  
    } 

    // thanks cheatcoder@github
    public void flash() {
        if (supportsFlash()) {
            if (!lightOn) {
                lightOn = true;
                mCamera.stopPreview();
                mCamera.setPreviewCallbackWithBuffer(this);// mCamera.setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);
                parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
                mCamera.setParameters(parameters);
                mCamera.startPreview();
            } else {
                lightOn = false;
                mCamera.stopPreview();
                mCamera.setPreviewCallbackWithBuffer(this); //setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);
                parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
                mCamera.setParameters(parameters);
                mCamera.startPreview();
            }
        }
    }

    // thanks http://ikravchenko.blogspot.com/2013/09/nexus-7-2013-torch-issue.html
    public boolean supportsFlash() {
         if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
             parameters = mCamera.getParameters();
             if (parameters.getFlashMode() != null) {
                List<String> supportedFlashModes = parameters.getSupportedFlashModes();
                 if (supportedFlashModes == null || supportedFlashModes.isEmpty() || supportedFlashModes.size() == 1 && supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)) {
                     return false;
                 }
                 return true;
             }
         }
         return false;
    }


    public void surfaceDestroyed(SurfaceHolder holder) {  
        // Surface will be destroyed when we return, so stop the preview.  
        // Because the CameraDevice object is not a shared resource, it's very  
        // important to release it when the activity is paused.  
        if (mCamera != null) {
            mCamera.stopPreview();  
            mCamera.setPreviewCallback(null);//setPreviewCallbackWithBuffer(null);
            mCamera.release();  
            mCamera = null;
        }
    }  

    public boolean isFrontCamera() {
        return isFrontCamera;
    }

    /* TODO: fix the bug with the null pointer exception */
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {  
        // Now that the size is known, set up the camera parameters and begin  
        // the preview.  
        if (mCamera != null) {
            parameters = mCamera.getParameters();

            //to do autofocus, need to set the parameters if available
            //http://stackoverflow.com/questions/11623266/camera-parameters-setfocusmode-is-not-working
            List<String> focusModes = parameters.getSupportedFocusModes();
            if (focusModes != null) {
                if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
                    parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                else if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                    parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                else if (focusModes.contains(Parameters.FOCUS_MODE_AUTO))
                    parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
            }

            //have to get previewSizes because not all devices support arbitrary previews
            //the following is from Stack Overflow
            int width = this.getWidth();
            int height = this.getHeight();
            Size best = null;
            List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
            // You need to choose the most appropriate previewSize for your app
            for (int i = 0; i < previewSizes.size(); i++) {
                Size size = previewSizes.get(i);
                if ((size.width <= width && size.height <= height) || (size.height <= width && size.width <= height))  {
                    if (best==null) {
                        best=size;
                    } else {
                        int resultArea=best.width*best.height;
                        int newArea=size.width*size.height;

                        if (newArea>resultArea) {
                            best=size;
                        }
                   }
                }
            }

            // make sure something is picked.  previewSizes is guarenteed to have at least one thing.
            if (best != null) {
                previewSize = best; 
            } else {
                previewSize = previewSizes.get(0);
            }

            parameters.setPreviewSize(previewSize.width, previewSize.height);
            pixels = new int[previewSize.width * previewSize.height];  
            mCamera.setParameters(parameters);

            //sets the camera callback to be the one defined in this class  
            mCamera.setPreviewCallbackWithBuffer(this);//setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);  
            bufferSize = previewSize.width*previewSize.height*ImageFormat.getBitsPerPixel(parameters.getPreviewFormat())/8;
            buffer = new byte[bufferSize];
            resetBuffer();

            if (!isPaused) mCamera.startPreview();

        }
    }

    public void pause(boolean isPaused) {
        this.isPaused = isPaused;
        if (isPaused) {
            parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            mCamera.setParameters(parameters);
            mCamera.stopPreview();
        } else {
            if (mCamera != null) {
                mCamera.setPreviewCallbackWithBuffer(this);//setPreviewCallback(this);//setPreviewCallbackWithBuffer(this);

                if(lightOn)
                    parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);

                mCamera.setParameters(parameters);
                mCamera.startPreview();
            }
        }
    }

    public void resetBuffer() {
        if (mCamera != null) {
            mCamera.addCallbackBuffer(buffer);
        }
    }


    @Override  
    public void onPreviewFrame(byte[] data, Camera camera) {  
        //transforms NV21 pixel data into RGB pixels  
        decodeYUV420SP(pixels, data, previewSize.width,  previewSize.height);  
        listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
    }  

    //Method from Ketai project! Not mine! See below...  
    void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {  

            final int frameSize = width * height;  

            for (int j = 0, yp = 0; j < height; j++) {       int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;  
              for (int i = 0; i < width; i++, yp++) {  
                int y = (0xff & ((int) yuv420sp[yp])) - 16;  
                if (y < 0)  
                  y = 0;  
                if ((i & 1) == 0) {  
                  v = (0xff & yuv420sp[uvp++]) - 128;  
                  u = (0xff & yuv420sp[uvp++]) - 128;  
                }  

                int y1192 = 1192 * y;  
                int r = (y1192 + 1634 * v);  
                int g = (y1192 - 833 * v - 400 * u);  
                int b = (y1192 + 2066 * u);  

                if (r < 0)                  r = 0;               else if (r > 262143)  
                   r = 262143;  
                if (g < 0)                  g = 0;               else if (g > 262143)  
                   g = 262143;  
                if (b < 0)                  b = 0;               else if (b > 262143)  
                   b = 262143;  

                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);  
              }  
         }  
    }  

}  

解决方案

You can calculate the elapsed time in onPreviewFrame(). For example:

    boolean isFirstTime = true;
    long startTime = 0;
    PreviewCallback callback = new PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            // TODO Auto-generated method stub
            if (isFirstTime) {
                isFirstTime = false;
                startTime = SystemClock.currentThreadTimeMillis();
                decodeYUV420SP(pixels, data, previewSize.width,  previewSize.height);  
                listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
            }
            else {
                long currentTime = SystemClock.currentThreadTimeMillis();
                long elapsedTime = currentTime - startTime;
                if (elapsedTime >= 500) { // trigger your event
                    startTime = currentTime;
                    decodeYUV420SP(pixels, data, previewSize.width,  previewSize.height);  
                    listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
                }
            }
        }
    };

Do not forget to reset the boolean value and start time when you switch the preview status.

这篇关于如何让每一个500毫秒后摄像头preVIEW框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆