Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何用camera2 API解决Nexus5x上的“反向景观”问题

我的应用程序使用camera2 API管理设备摄像头的预览。但问题是,我的设备是一个Nexus5x,有翻转传感器和众所周知的反向景观“问题”。我在某个地方读到,camera2 api“自动”处理这个问题,但我认为只有在设置捕获会话时针对surface对象的表面,这才是正确的。但是相反,我的目标是建立在表面纹理之上的表面,我进一步使用它来渲染预览以获得立体视图,并且随着这种方法问题的持续存在,我得到了颠倒的框架。下面是代码,这几乎是使用camera2 API时的常规工作流。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void openCamera() {
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    Log.e(TAG, "is camera open");
    try {
        cameraId = manager.getCameraIdList()[CAMERA_SOURCE];
        CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
        StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        assert map != null;
        imageDimension = map.getOutputSizes(SurfaceTexture.class)[CAMERA_SOURCE];
        // Add permission for camera and let user grant the permission
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
            return;
        }
        manager.openCamera(cameraId, stateCallback, null);

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
    Log.e(TAG, "openCamera X");
}

private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(CameraDevice camera) {
        //This is called when the camera is open
        Log.e(TAG, "onOpened");
        cameraDevice = camera;
        createCameraPreview();
    }
    @Override
    public void onDisconnected(CameraDevice camera) {
        cameraDevice.close();
    }
    @Override
    public void onError(CameraDevice camera, int error) {
        cameraDevice.close();
        cameraDevice = null;
    }
};

protected void createCameraPreview() {
    try {

        // Create ImageReader Surface
        int max = 2;
        mReader = ImageReader.newInstance(mWidth, mHeight, ImageFormat.YUV_420_888, max);
        ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader mReader) {
                Image image = null;
                image = mReader.acquireLatestImage();
                if (image == null) {
                    return;
                }                           

                byte[] bytes = convertYUV420ToNV21(image);

                nativeVideoFrame(bytes);
                image.close();   
            }
        };      

        mReader.setOnImageAvailableListener(readerListener, mBackgroundHandler);

        // Create Texture Surface
        texture = createTexture();
        mSurfaceTexture = new SurfaceTexture(texture);
        mSurfaceTexture.setOnFrameAvailableListener(this);
        mSurfaceTexture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
        mSurface = new Surface(mSurfaceTexture);

        //Attach surfaces to CaptureRequest
        List<Surface> outputSurfaces = new ArrayList<Surface>(2);
        outputSurfaces.add(mReader.getSurface());
        outputSurfaces.add(mSurface);
        captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        captureRequestBuilder.addTarget(mSurface);
        captureRequestBuilder.addTarget(mReader.getSurface());

        //Define the capture request
        cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback(){
                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                        //The camera is already closed
                        if (null == cameraDevice) {
                            return;
                        }
                        // When the session is ready, we start displaying the preview.
                        cameraCaptureSessions = cameraCaptureSession;
                        updatePreview();
                    }
                    @Override
                    public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                        Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
                    }
                }, null);
        } catch (CameraAccessException e) {
             e.printStackTrace();
        }
}

protected void updatePreview() {
    if(null == cameraDevice) {
        Log.e(TAG, "updatePreview error, return");
    }
    captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
    try {
        cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

我的问题是:我该怎么做才能自己解决逆向景观问题?哪一行代码,我应该在哪里添加?

谢谢,

JM

EN

回答 1

Stack Overflow用户

发布于 2017-12-15 07:05:41

由于您使用的是SurfaceTexture和ImageReader,所以您必须自己处理轮调。Camera2 API与SurfaceView或TextureView一起使用时会自动处理旋转。

这就是说,一旦您通过ImageReader.OnImageAvailableListener回调获得帧的字节,就可以手动旋转它们,或者更好的是直接在GPU上执行对OpenGL纹理的操作。

请注意,旋转180°等效于垂直翻转一次,水平翻转一次,在OpenGL上,这意味着可以:

  • 旋转180°平面绘制相机纹理
  • 比例为-1绘制相机纹理的平面的x和y。
  • 改变摄像机平面的紫外线
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39126356

复制
相关文章
如何用Python解决最优化问题?
现有5个广告投放渠道,分别是日间电视、夜间电视、网络媒体、平面媒体、户外广告,每个渠道的效果、费用及限制如下表所示:
1480
2019/06/02
6.2K0
webpack配置proxy反向代理,解决跨域问题
目的:为了解决前端和后端联调数据,出现的跨域问题,通过配置反向代理,可以更好的联调数据
青梅煮码
2023/01/14
2.8K0
webpack配置proxy反向代理,解决跨域问题
Openresty 反向代理 api服务
反向代理(Reverse Proxy)方式是指用代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
Devops海洋的渔夫
2019/05/30
1.6K0
Python|如何用递归解决汉诺塔问题?
n个大小不同的圆盘按照从小到大的顺序放在A柱子上,要求每次搬动1个圆盘,且在搬动过程中,大圆盘在下,小圆盘在上,将所有圆盘从A柱子移动到C柱子,中间可以借助B柱子,请实现搬动过程。
算法与编程之美
2020/04/15
7040
WebSocket使用Nginx反向代理解决Wss服务问题
WebSocket 可以减小客户端与服务器端建立连接的次数,减小系统资源开销,只需要一次 HTTP 握手,整个通讯过程是建立在一次连接/状态中,也就避免了 HTTP 的非状态性,服务端会一直与客户端保持连接,直到你关闭请求,同时由原本的客户端主动询问,转换为服务器有信息的时候推送
沈唁
2019/12/12
18.6K0
vue跨域解决方案反向代理_怎么解决跨域问题
Access to XMLHttpRequest at ‘http://192.168.2.92:3000/api/b/home’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.
全栈程序员站长
2022/11/10
8730
vue跨域解决方案反向代理_怎么解决跨域问题
如何用SingleThreadModel解决多线程安全问题
前面介绍的都是普通的Servlet。对于每一个用户请求,那些Servlet都会用线程的方式给予应答。这样比较节省系统的资源。Sun公司也给出了另外一种方法,就是这节要介绍的SingleThreadModel的方法。当implement这个接口以后,你的Servlet就变成了另外一种模式工作。即,每一个新用户的请求,都会生成一个新的Servlet实例来应答。这种方法有两个方面的弊病。一是性能太差,最后会把机器拖累死。还有一条就是有时解决不了实际问题。每个servlet类实例都有自己独立的变量。如果我们的本意就是想让客户线程之间进行这些变量的交流。这种方法就无法做到。就像还有人建议的,用局部变量来代替类变量一样,有时也解决不了实际当中的算法问题。因为我们有时就需要用一个类似类变量一样的东西,来控制全局。即使这种方法这不好,那不好,现实中很多很多工程师也说不好。我还是给出了例子,让大家看看结果。
马克java社区
2021/07/08
3460
解决redis远程连接不上的问题
redis现在的版本开启redis-server后,redis-cli只能访问到127.0.0.1,因为在配置文件中固定了ip,因此需要修改redis.conf(有的版本不是这个文件名,只要找到相对应的conf后缀的文件即可)文件以下几个地方。
人生不如戏
2018/09/27
14.6K0
反向代理的攻击面 (上)
近年来,很多安全研究人员研究攻击的文章中都或多或少涉及到反向代理。在扫描工具能实现检测反向代理种类时,我开始深入研究反向代理的具体实现流程。
随心助手
2019/10/15
1.6K0
Android Camera2 API 同时使用前后摄像头预览
不久前,我承担了从运行Android的设备的前后摄像头获取同步提要的任务。 像往常一样,我去了Stack Overflow,然后去了GitHub,然后去了其他博客,才意识到我可能独自一人。 难过的感觉吧?
字节流动
2022/09/26
3.3K0
Android Camera2 API 同时使用前后摄像头预览
[译] 如何用 Android vitals 解决应用程序的质量问题
对于一个应用开发者来说,没有比开心的用户更好的衡量成功的标准,而且最好是有很多这样的用户。实现这一目标的最佳方式是拥有一个人人都想用的优秀应用,不过我们所说的“优秀”指的是什么呢?它可以归结为两件事:功能和应用质量。前者最终取决于你的创造力和选择的商业模式,而后者可以客观地衡量和改进。
Android 开发者
2018/08/02
2.3K0
[译] 如何用 Android vitals 解决应用程序的质量问题
如何用Synchronied解决Servlet多线程安全问题?
马克-to-win:我们先铺垫Servlet的多线程基础知识。到现在为止,我们所接触到的Servlet都是这样的:第一个人访问Servlet的时候,Servlet会被实例化。之后的人再访问这个Servlet的时候,这个Servlet就不再被实例化了,而是采取线程的模式。用每一个由这个servlet而来的线程来应答来请求的客户。这样的话,Servlet的实例变量,实际上是被所有客户的线程共享的。这样就会出现线程安全的问题。一谈到多线程安全,就需要谈到我"Java初级"部分第六章的那个多线程安全的例子。这里基本还是用那个例子,只不过是放在Servlet环境下。那里对Critical data(关键数据[多个线程同时会修改的数据])的解决方案,就是在访问Critical data的方法前面加上关键字Synchronized。这里建议的解决方案也是这样。马克-to-win:我们先看一个没有加Synchonized的 critical data的例子。见下面例:2.1.1,还是像"Java初级"部分第六章那里一样,onlySellOne对于一个人来讲,一次只能卖一本书。对于本例来讲,我们用一个浏览器模拟一个人。观察浏览器,我们发现,对于有的人(http-8080-Processor25)来讲,开始还是18本书,买了一本书之后(调用一次onlySellOne),自己一看,还剩下16本书。这里显然出现了问题。问题就在于,有其他人同时也在买书。关键数据(bookNum)可以被多个线程同时修改。对于例:2.1.2,我们通过在onlySellOne方法前面加上Synchronized关键字,使得这个方法,在被任何线程调用时,其他线程就不能再调用,而只能排队等候。这样,结果就完美了。即使两个浏览器是同时运行的,数据也是一个一个减下来的。
马克java社区
2021/07/08
4140
解决moco框架API在cycle方法缺失的问题
我在使用moco框架过程中,遇到一个问题,在官方文档中给出了cycle的方法,表示循环返回一个数组里面的response,但是在查看API的时候并没有发现这个cycle()方法,所以觉得自己写了一个responsehandle,并且重写了cycle()方法。
FunTester
2019/07/27
4440
如何解决视频条带化的问题(上)
原文 https://sonnati.wordpress.com/2020/01/12/defeat-banding-part-i/
LiveVideoStack
2020/02/19
1.6K0
Django 解决跨域访问API失败问题
https://www.djangoproject.com/download/2.0.13/tarball/
授客
2020/09/22
2.6K0
解决XP上WPF显示gif卡的问题
初始化过程或者检测升级用到GIF作为中间等待,但使用的MediaElement在某些XP版本上,GIF会卡着不动,去网上查了查,解决方案不少:HTTP://www.cnblogs.com/ zjoch / p / 3679638.html,但感觉不怎么好用,最后在NuGet里安装WPF动画GIF(引用WpfAnimatedGif.dll),它是在图片里附加了一个属性,可以加载图片或gif资源,前台代码就两行:
kiki.
2022/09/29
5190
Mysql解决主从慢同步问题(上)
一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) —–>IO Thread (从) —–> SQL Thread(从)。复制出现延迟一般出在两个地方
陈不成i
2021/06/17
2K0
点击加载更多

相似问题

Camera2 API有可能选择景观捕捉吗?

10

Camera2 API问题

11

Camera2 API OIS问题

19

Camera2 API上的getSupportedFlashModes

20

Nexus5X记录视频倒转使用MediaRecorder和camera2

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文