如何每500ms获取一次相机预览帧

2023-12-12

我正在开发示例应用程序,它通过 android 中的相机为我提供指向图像或对象的颜色代码。我的应用程序与此应用程序类似,我正在使用this为此的应用程序代码。

使用此应用程序代码,我可以连续获取相机预览帧,并为我提供当前预览帧的颜色代码。我想让它延迟一些。我只想每 500 毫秒后获取 1 个相机预览帧。

我怎样才能做到这一点,我需要在这段代码中进行哪些修改。

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);  
              }  
         }  
    }  

}  

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

    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);
                }
            }
        }
    };

切换预览状态时,不要忘记重置布尔值和开始时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何每500ms获取一次相机预览帧 的相关文章

  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 图像作为电子邮件附件

    我想构建一个应用程序 我可以在电子邮件中附加图像 打开图像并将其设置为我的壁纸 我想让它跨平台 所以你能告诉我是否可以使用phonegap 或者我是否必须为iphone和android构建一个本机应用程序 您好 如果您只想通过电子邮件附加图
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • 我应该释放或重置 MediaPlayer 吗?

    我有自己的自定义适配器类 称为 WordAdapter 并且我正在使用媒体播放器 名为pronounce WordAdapter 类中的全局变量 我有不同的活动 其中每个列表项都有线性布局 名为linearLayout 我正在设置onCli
  • 专门针对 JSP 的测试驱动开发

    在理解 TDD 到底是什么之前 我就已经开始编写测试驱动的代码了 在没有实现的情况下调用函数和类可以帮助我以更快 更有效的方式理解和构建我的应用程序 所以我非常习惯编写代码 gt 编译它 gt 看到它失败 gt 通过构建其实现来修复它的过程
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • 如何在 Android 中从 WorkManager 取消工作?

    我已经保存了 WorkManagerUUID转换成String在领域数据库中 这是代码 Constraints constraints new Constraints Builder setRequiredNetworkType Netwo
  • Dagger 2 没有生成我的组件类

    我正在使用 Dagger 2 创建我的依赖注入 几个小时前它还在工作 但现在不再生成组件 这是我创建组件的地方 public class App extends Application CacheComponent mCacheCompon
  • Eclipse 启动时崩溃;退出代码=13

    I am trying to work with Eclipse Helios on my x64 machine Im pretty sure now that this problem could occur with any ecli
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • Android - 以编程方式选择菜单选项

    有没有办法以编程方式选择菜单选项 基本上 我希望视图中的按钮能够执行与按特定菜单选项相同的操作 我正在考虑尝试调用 onOptionsItemSelected MenuItem item 但我不知道要为菜单项添加什么 是的 有一种方法可以选
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db
  • 发布的 Android apk 出现错误“包文件未正确签名”

    我最近将我的应用程序上传到 Android 市场 但是由于错误 下载时它拒绝运行 包文件未正确签名 我首先使用 eclipse 发布了数据包 右键单击导出 创建密钥库然后发布 但它拒绝工作 然后我下载了 keytool 和 jarsigne

随机推荐

  • Swift 符合协议子类

    在我的应用程序中 我有多个依赖于模型的 UIView 子类 每个班级都采用 Restorable 保存模型超类的协议 每个子模型都描述了特定的 UIView 不常见属性 Super model public protocol StoryIt
  • 防止键盘关闭

    我在这个实现上有点挣扎 我正在构建我的第一个 Hello World android cordova 应用程序需要键盘始终显示并避免像用户单击后退按钮或任何其他输入时那样隐藏它 为什么 基本上我的 HTML 中没有任何输入元素来触发焦点并显
  • 最小化 C 中浮点错误的经验法则?

    关于最小化浮点运算中的错误 如果我在 C 中有如下操作 float a 123 456 float b 456 789 float r 0 12345 a a r b 如果我将乘法和减法步骤分开 计算结果会改变吗 即 float c r b
  • 使用 foreach 从数据库中获取数据 - 从上到下

    数据库 id name 1 aaa 2 bbb 3 ccc 250 zz3 foreach datafromdb as value echo value gt name 这告诉我 aaa bbb ccc zz3 从左到右 if table
  • 使用 DNS 重定向到另一个带有路径的 URL [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在尝试通过 DNS 将一个域重定向到另一个域 我知道使用 IN CNAME 是可能的 www proof com IN CNAME www proof two com 我需要的是
  • 在 JavaScript 中停止回发

    我有一个带有 JQuery Thickbox 的 ASP Web 表单 我有一个在用户单击时打开 Thickbox 的图像 一旦打开厚盒 它会向我显示一个包含多行的网格和一个用于选择一行的按钮 在用户选择记录后 它返回到所选记录的主页并导致
  • Cordova本地通知Android插件2.2升级

    我正在使用 Phonegap Cordova 2 2 在 Android 上开发 提醒 应用程序 用户输入一个具体的提醒日期 我应该准时通知他 我使用 Android 的通知插件 但它支持早期版本的手机间隙 我按照本教程解决了cordova
  • Xamarin.Forms 中选项卡式页面中的标题截止

    Android 中的标签页标题被截断 但在 iOS 设备上运行良好 我正在使用这个代码 public Tabbar this BarTextColor Color Maroon New Feed var navigationNewFeed
  • 嵌套函数的实现

    我最近发现gcc允许定义嵌套函数 在我看来 这是一个很酷的功能 但我不知道如何实现它 虽然通过传递上下文指针作为隐藏参数来实现对嵌套函数的直接调用当然并不困难 但 gcc 还允许获取指向嵌套函数的指针并将该指针传递给任意其他函数 该函数又可
  • 向表中的每一行插入一个随机数

    我目前有一个包含大约 600 000 行的 oracle 表 lovalarm 我需要能够运行一个查询 该查询将循环遍历每一行并将字段 lovsiteid 更新为 14300 到 17300 之间的随机数 到目前为止我有 update lo
  • 一天的时间跨度怎么可能只有 8 个小时?

    我保存了以分钟为单位的持续时间 并希望输出 1 天 5 小时 30 分钟 目前 我将分钟添加到时间跨度中并执行如下操作 TimeSpan ts new TimeSpan 0 0 1800 0 Response Write ts Days d
  • 如何使用Beautifulsoup解析网站

    我是网络抓取新手 我想获取页面的 html 但是当我运行该程序时 我得到 html 为空并且控制台显示 javascript from bs4 import BeautifulSoup import requests import urll
  • 未指定网络安全配置,使用平台默认值

    我正在尝试打印值列表ListView来自网页 我有这两个权限
  • 在 Jquery 中创建无限循环

    HTML结构是这样的 ul class innerfade li style display none some Text li li style display none bla bla bla li li style display n
  • 如何在psql中切换数据库?

    在MySQL中 我使用了use database name 什么是psql相等的 在 PostgreSQL 中 您可以使用 connect客户端工具psql的元命令 connect DBNAME 或者简而言之 c DBNAME
  • 使用 NEST C# 在 Elastic Search 中使用多个索引进行全文搜索

    我正在尝试使用 NEST 客户端搜索多个索引 Elasticsearch 我只需点击以下链接 叠加帖子 如何使用 Nest ElasticSearch 在多个索引内进行搜索 唯一的区别是我的索引已经存在但没有返回 示例代码 using Sy
  • 单击子元素也会触发其父元素的单击事件[重复]

    这个问题在这里已经有答案了 Scenario 我的主干应用程序中的视图由几个部分组成boxes which are div elements 当用户单击一个框并按住鼠标按钮 500 毫秒时 我想显示一个delete左上角的按钮 当用户点击其
  • C++ 委托构造函数

    你好 我对 Java 比 C 更熟悉 test h class Test private int a b c public Test int a int b int c test c Test Test int a int b int c
  • 如何使用 FTP 下载 R 包

    我需要在无法访问 Internet 的 Windows 7 PC 上支持 R 环境 我想下载 最终下载到 DVD 所有 5 000 个软件包的当前版本 以供这台 PC 上的 R 用户使用 是否有 FTP 脚本或其他好方法来下载 R 包的所有
  • 如何每500ms获取一次相机预览帧

    我正在开发示例应用程序 它通过 android 中的相机为我提供指向图像或对象的颜色代码 我的应用程序与此应用程序类似 我正在使用this为此的应用程序代码 使用此应用程序代码 我可以连续获取相机预览帧 并为我提供当前预览帧的颜色代码 我想