以编程方式确定android中的相机质量

以编程方式确定android中的相机质量,android,camera,record,Android,Camera,Record,我想用摄像头(前置摄像头)录制视频,但在不同的设备中,前置摄像头的录制质量是不同的,当我们想用摄像头录制一些视频时,我们必须为我们的MediaRecorder设置CamrecorderProfile,问题是,当我将CamcorderProfile.QUALITY_720P用作CamrecorderProfile时,有些设备的前置摄像头不支持720P分辨率。 如果我们使用QUALITY_LOW,我们可以在所有设备中录制,但在某些设备中,输出视频将如下所示: 那么有没有办法找出摄像机的质量,因此,

我想用摄像头(前置摄像头)录制视频,但在不同的设备中,前置摄像头的录制质量是不同的,当我们想用摄像头录制一些视频时,我们必须为我们的MediaRecorder设置CamrecorderProfile,问题是,当我将CamcorderProfile.QUALITY_720P用作CamrecorderProfile时,有些设备的前置摄像头不支持720P分辨率。 如果我们使用QUALITY_LOW,我们可以在所有设备中录制,但在某些设备中,输出视频将如下所示:


那么有没有办法找出摄像机的质量,因此,我们可以使用适当的质量在每台设备中进行录制

您可以使用
摄像头检查支持的分辨率。参数
api

好的,我将为您提供一个快速启动代码。通过此代码,我可以获得安装了我的应用程序的任何手机的最佳参数,这样它在运行时不会拉伸或显示不平滑捕获。您最需要的代码是
SurfaceChanged

    public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where to draw.
    try {
        mCamera = Camera.open(); // WARNING: without permission in Manifest.xml, crashes
                }
    catch (RuntimeException exception) {
        //Log.i(TAG, "Exception on Camera.open(): " + exception.toString());
        Toast.makeText(getContext(), "Camera broken, quitting :(",Toast.LENGTH_LONG).show();
        // TODO: exit program
    }

    try {
        mCamera.setPreviewDisplay(holder);
        updateBufferSize();

        mCamera.addCallbackBuffer(mBuffer); // where we'll store the image data
        mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
            public synchronized void onPreviewFrame(byte[] data, Camera c) {

                if (mCamera != null) { // there was a race condition when onStop() was called..
                    mCamera.addCallbackBuffer(mBuffer); // it was consumed by the call, add it back
                }
            }
        });
    } catch (Exception exception) {
        //Log.e(TAG, "Exception trying to set preview");
        if (mCamera != null){
            mCamera.release();
            mCamera = null;
        }
        // TODO: add more exception handling logic here
    }
}

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.
    //Log.i(TAG,"SurfaceDestroyed being called");
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
}

// FYI: not called for each frame of the camera preview
// gets called on my phone when keyboard is slid out
// requesting landscape orientation prevents this from being called as camera tilts
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    //Log.i(TAG, "Preview: surfaceChanged() - size now " + w + "x" + h);
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    try {
        mParameters = mCamera.getParameters();

           int picH = mParameters.getPictureSize().height;
             int picW = mParameters.getPictureSize().width;
             int preH = mParameters.getPreviewSize().height;
             int preW = mParameters.getPreviewSize().width;
             float scale = ((float)(picH*preW)) / ((float)(picW*preH));


             float bff = 0;
             try {
                 List<Camera.Size> supportedSizes = null;

                 //maximize supported resizes, TODO remove as hardcode
                 w*=1.5;
                 h*=1.5;

                 // On older devices (<1.6) the following will fail
                 // the camera will work nevertheless
                 supportedSizes = mCamera.getParameters().getSupportedPreviewSizes();

                 // preview form factor
                 float ff = (float) w / h;
                 System.out.println("TAG" + "Screen res: w:" + w + " h:" + h + " aspect ratio:" + ff);

                 // holder for the best form factor and size
                 int bestw = 0;
                 int besth = 0;
                 Iterator<Camera.Size> itr = supportedSizes.iterator();

                 // we look for the best preview size, it has to be the closest
                 // to the
                 // screen form factor

                 while (itr.hasNext()) {
                     Camera.Size element = itr.next();
                     // current form factor
                     float cff = (float) element.width / element.height;
                     // check if the current element is a candidate to replace
                     // the best match so far
                     // current form factor should be closer to the bff
                     // preview width should be less than screen width
                     // preview width should be more than current bestw
                     // this combination will ensure that the highest resolution
                     // will win
                     Log.d("TAG", "Candidate camera element: w:"
                             + element.width + " h:" + element.height
                             + " aspect ratio:" + cff);
                     if ((ff - cff <= ff - bff) && (element.width <= w)
                             && (element.width >= bestw)) {
                         bff = cff;
                         bestw = element.width;
                         besth = element.height;
                     }
                 }
                 System.out.println("TAG" + "Chosen camera element: w:" + bestw + " h:" + besth + " aspect ratio:" + bff);
                 // Some Samsung phones will end up with bestw and besth = 0
                 // because their minimum preview size is bigger then the screen
                 // size.
                 // In this case, we use the default values: 480x320
                 if ((bestw == 0) || (besth == 0)) {
                     Log.d("Mixare", "Using default camera parameters!");
                     bestw = 480;
                     besth = 320;
                 }
                 mParameters.setPreviewSize(bestw,besth);
             } catch (Exception ex) {
                 mParameters.setPreviewSize(480,320);

                 bff=1.5f;
             }
             makeResizeForCameraAspect(bff);
        for (Integer i : mParameters.getSupportedPreviewFormats()) {
            //Log.i(TAG, "supported preview format: " + i);
        } 

        List<Size> sizes = mParameters.getSupportedPreviewSizes();
        for (Size size : sizes) {
        Log.i(VIEW_LOG_TAG, "supported preview size: " + size.width + "x" + size.height);
        }
        mCamera.setParameters(mParameters); // apply the changes
    } catch (Exception e) {
        // older phone - doesn't support these calls
    }

    updateBufferSize(); // then use them to calculate

    Size p = mCamera.getParameters().getPreviewSize();
    //Log.i(TAG, "Preview: checking it was set: " + p.width + "x" + p.height); // DEBUG
    mCamera.startPreview();
}

private void makeResizeForCameraAspect(float cameraAspectRatio) {
    ViewGroup.LayoutParams layoutParams=this.getLayoutParams();
    int matchParentWidth=this.getWidth();
    int newHeight=(int)(matchParentWidth/cameraAspectRatio);
    if(newHeight!=layoutParams.height){
        layoutParams.height=newHeight;
        layoutParams.width=matchParentWidth;
        this.setLayoutParams(layoutParams);
        this.invalidate();
    }
}



public Parameters getCameraParameters(){
    return mCamera.getParameters();
}

public void setCameraFocus(AutoFocusCallback autoFocus){
    mCamera.getParameters();
    mCamera.getParameters();
    if (mCamera.getParameters().getFocusMode().equals(Parameters.FOCUS_MODE_AUTO) ||
            mCamera.getParameters().getFocusMode().equals(Parameters.FOCUS_MODE_MACRO)){
        mCamera.autoFocus(autoFocus);
    }
}
public void surfaceCreated(SurfaceHolder持有者){
//曲面已创建,获取摄影机并告诉其绘制位置。
试一试{
mCamera=Camera.open();//警告:如果没有Manifest.xml中的权限,将崩溃
}
捕获(运行时异常){
//Log.i(标记“Camera.open()上的异常:”+Exception.toString());
Toast.makeText(getContext(),“相机坏了,退出:(”,Toast.LENGTH_LONG).show();
//TODO:退出程序
}
试一试{
mCamera.setPreviewDisplay(支架);
updateBufferSize();
mCamera.addCallbackBuffer(mBuffer);//我们将在哪里存储图像数据
setPreviewCallbackWithBuffer(新的PreviewCallback(){
公共同步void onPreviewFrame(字节[]数据,摄像头c){
如果(mCamera!=null){//调用onStop()时存在争用条件。。
mCamera.addCallbackBuffer(mBuffer);//它已被调用占用,请将其添加回
}
}
});
}捕获(异常){
//Log.e(标记“尝试设置预览的异常”);
if(mCamera!=null){
mCamera.release();
mCamera=null;
}
//TODO:在此处添加更多异常处理逻辑
}
}
公共空间表面覆盖(表面覆盖物持有人){
//当我们返回时,曲面将被破坏,因此请停止预览。
//因为CameraDevice对象不是共享资源,所以它非常有用
//当活动暂停时释放它很重要。
//Log.i(标记“被调用的表面置换”);
mCamera.stopPreview();
mCamera.release();
mCamera=null;
}
//仅供参考:不为相机预览的每一帧调用
//当键盘滑出时在我的手机上被呼叫
//请求横向定向可防止将其称为摄影机倾斜
公共无效表面更改(表面持有人,整数格式,整数w,整数h){
//Log.i(标记,“预览:surfaceChanged()-size now”+w+“x”+h);
//现在已经知道大小,请设置相机参数并开始
//预览。
试一试{
mParameters=mCamera.getParameters();
int picH=mpareters.getPictureSize().height;
int picW=mpareters.getPictureSize().width;
int preH=mpareters.getPreviewSize().height;
int preW=mpareters.getPreviewSize().width;
浮动刻度=((浮动)(picH*preW))/((浮动)(picW*preH));
浮动bff=0;
试一试{
列表支持的大小=空;
//最大化支持的大小调整,TODO作为硬代码删除
w*=1.5;
h*=1.5;
//在旧设备上(