Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无目的捕获图像,在不同设备上提供不同的输出_Android_Android Camera - Fatal编程技术网

Android 无目的捕获图像,在不同设备上提供不同的输出

Android 无目的捕获图像,在不同设备上提供不同的输出,android,android-camera,Android,Android Camera,我的要求是既不显示相机预览,也不使用相机意图进行图像捕获 在那里,我找到了一种适合我的第一台测试设备(Galaxy tab 7)的方法 我的CaptureImage功能如下 private void CaptureImage() { int FrontCameraFound = getCameraID(); if (FrontCameraFound != -1) { mCamera = Camera.open(FrontCameraFoun

我的要求是既不显示相机预览,也不使用相机意图进行图像捕获

在那里,我找到了一种适合我的第一台测试设备(Galaxy tab 7)的方法

我的
CaptureImage
功能如下

private void CaptureImage() {
        int FrontCameraFound = getCameraID();
        if (FrontCameraFound != -1) {
            mCamera = Camera.open(FrontCameraFound);

            parameters = mCamera.getParameters();

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

            Camera.PictureCallback mCall = new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {

                    bmp = BitmapFactory.decodeByteArray(data, 0, data.length);

                    // set bitmap tp image view just to check 
                    // if image capture proper, testing purpose
                    iv_image.setImageBitmap(bmp);

                    mCamera.stopPreview();
                    mCamera.release();
                    mCamera = null;
                }
            };
            mCamera.takePicture(null, null, mCall);
        }
    }
getCameraID
功能如下

private int getCameraID() {
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();

    for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); camIdx++) {
        Camera.getCameraInfo(camIdx, cameraInfo);
        // for capture image from back camera
        // If want to capture from front 
        // then change it to CAMERA_FACING_FRONT
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
            try {
                return camIdx;
            } catch (RuntimeException e) {

            }
        }
    }
    return -1;
}
不可能检查每台设备的代码,我只在5台设备上测试了我的代码,2台设备会导致问题,所以有没有标准的方法可以在没有意图和预览的情况下从相机获取图像

请注意,我在清单中包含并将最低sdk版本设置为9

更新:
在4.1 Nexus Galaxy的Camera.java类中,从第1061行开始,Nexus Galaxy拍摄失败,下面是一个例子,它给了我一些信息,说明了在Camera.java中的原生拍摄(msgType);函数。java确实抛出了一个问题,android设备中的相机处理是一个主要的PITA-不同的设备(甚至是同一设备上的android版本)可以而且肯定会有不同的表现。基本上,你们是在和设备上的一些恶魔进程交谈,它们彼此不同

我并没有解决所有问题的办法,但以下是我迄今为止的发现

  • 并非所有分辨率都能正常工作,即使它们在相机参数中显示。设置相机时必须测试它们,以防出现问题
  • 预览数据通过映射的内存区域提供给您
  • NV21格式总是提供的,应该是默认的,但我会查询相机设置。当你打开相机时,它可以有一些设置从其他应用程序使用相机刚刚。(据说,相机将重置为默认值,当你打开它)
我已经开发了一些为JavaOCR项目开发的相机管理工具,它可以在大多数设备上运行。请随意使用它作为灵感:


您需要使用Camera.setOneShotPreviewCallback方法,然后处理图像

尝试使用YuvImage并在将其传递到bitmapfactory之前对其进行压缩,如下所示:

YuvImage yuvimage = new YuvImage(byteArr, ImageFormat.NV21, width, height, null);
    Rect rect = new Rect(0, 0, width, height);
    ByteArrayOutputStream outstr = new ByteArrayOutputStream();
    yuvimage.compressToJpeg(rect, 100, outstr);
    Bitmap bm = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());
编辑:


您必须使用曲面视图,但曲面视图可以隐藏在另一个视图下,因此它在屏幕上不可见,但仍然存在并处于活动状态。

经过多次搜索,我发现相机预览是必要的,我想知道我的代码如何在某些设备上运行良好,即使它有故障

任何解决办法都是


我们需要在曲面视图上保留摄影机预览,并且我们可以将该曲面视图隐藏在任何其他视图后面,我在framelayout中获取曲面视图(我知道它已被弃用)在它上面我拍摄图像视图,对于表面视图,我只拍摄80*80 dp的表面视图,因为像30*30 dp这样的小表面视图无法正常工作,并且再次出现错误。

我想在用户不知道的情况下从相机拍摄图像,并且必须兼容所有API级别为9+的设备,正如我在某些设备中提到的,它工作正常,但对于某些设备来说在Galaxy Nexus上的logcat中没有提到,显示从
onCreate()
调用
takePicture()
方法,而不是从
CaptureImage()调用
方法。这是否正确?抱歉,之前我命名的CaptureImage函数已被表面更改。我编辑了日志,但未显示摄像头预览和摄像头意图,您如何拍摄图像?是“是否要拍摄手机屏幕的图像?”“?不,我不想捕捉手机屏幕,正如我提到的,在Xoom、Galaxy tab、LG net、HTC wildfire中,代码运行良好,没有向用户显示预览,也没有使用相机意图,但对于两台设备,我遇到了一个非常愚蠢的问题:是否有必要通过表面或表面纹理显示预览?”??由于没有预览,我无法在4.1中捕获图像,顺便说一句,感谢您共享代码,我将查阅文档,其中说明必须通过完全配置的曲面视图并启动预览才能拍照。但是,不要求曲面视图位于前面且可见。看:所以你们想说,若我们保持表面不可见,这个问题就会得到解决,对吗?我不能保证你们的问题会通过这个得到解决。但请记住,decodeBitmap()等待压缩的位图数据,而pictureCalback()不一定会将正确的压缩格式传递给您。你必须检查(或调整)摄像机配置以匹配这些格式并正确解码我在从字节中提取位图时不会遇到问题,我尝试将不可见设置为surface,但仍然没有成功。感谢Tomas的回答,但我的主要问题是,当takePicture函数调用它时,它立即失败,所以使用setOneShotPreviewCallback(previewCallback)时,PictureTaken没有调用但如何在没有预览的情况下执行预览回调?如Konstantin Pribluda answer评论中所述,您必须有一个曲面视图,并且不能将其设置为不可见,但您可以使用一个小的(1X1像素)曲面视图并在其上放置另一个视图,结果是一个用户看不见的表面,我想这就是你想要的。
YuvImage yuvimage = new YuvImage(byteArr, ImageFormat.NV21, width, height, null);
    Rect rect = new Rect(0, 0, width, height);
    ByteArrayOutputStream outstr = new ByteArrayOutputStream();
    yuvimage.compressToJpeg(rect, 100, outstr);
    Bitmap bm = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());