【问题标题】:How to capture the image as shown in camera preview with out chopping its length and width如何在不切断其长度和宽度的情况下捕捉相机预览中显示的图像
【发布时间】:2015-04-23 12:42:21
【问题描述】:

我正在制作一个 android 自定义相机应用程序。在其中,我想从前置摄像头拍照保存并将其展示给用户。但我在这里面临一些问题。有些设备运行得非常完美,但其他设备运行不佳,事实上它们正在从顶部截断图像的长度。我问了另一个问题here,但没有找到好的答案

我正在与三件事作斗争,那就是相机的最佳分辨率,屏幕尺寸(宽度和高度)以及相机拍摄的位图的宽度和高度。我的应用在其他设备上运行良好,但在 Lg 设置上却不行,因为它的分辨率太高了。

我将前置摄像头的最佳分辨率设置为 1776 * 1080,而我将屏幕尺寸设置为 1440 * 2392,但摄像头拍摄的照片的宽度和高度为 1280 * 960。现在问题在这里仍然存在。我不知道如何获得与相机预览所示相同的图像,我不希望它的任何角落被切掉。那么如何做到这一点。以下是我获得最佳相机尺寸的代码....

  public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio=(double)h / w;

    if (sizes == null) return null;

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

这是我获取屏幕宽度和高度的方法

 DisplayMetrics displaymetrics = new DisplayMetrics();
       activity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int screenHeight = displaymetrics.heightPixels;
        int screenWidth = displaymetrics.widthPixels;

以下是我设置参数的方式:

    Camera.Size previewSize = getOptimalPreviewSize(previewSizes,screenWidth,screenHeight);
 parameters.setPreviewSize(previewSize.width,previewSize.height);
parameters.setZoom(Camera.Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX);

            camera.setParameters(parameters);

**

那么我怎样才能获得相机预览所示的完整图片。 ?请帮帮我

**

【问题讨论】:

  • 如果您想获得与相机预览相同的图像,您的相机需要setPictureSize()。首先,循环getSupportedPictureSizes(),然后找到最接近您的预览尺寸(具有相同的纵横比)。
  • 您有解决方案吗?这里有同样的问题。
  • @DuyPham 你能用一些代码解释一下吗?

标签: android camera android-camera


【解决方案1】:

CameraView.class

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore.Images;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;

public class CameraView extends Activity implements SurfaceHolder.Callback,OnClickListener {
    OutputStream output;
    File dir;
    private static final String TAG="CameraTest";
    Camera camera;
    boolean mPreviewRunning=false;
    public void onCreate(Bundle icicle){

        super.onCreate(icicle);
        Log.e(TAG,"onCreate");
        File filepath=Environment.getExternalStorageDirectory();
        dir=new File(filepath.getAbsolutePath()+"/Cam/");
        dir.mkdirs();
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.cameraview);
        mSurfaceView=(SurfaceView)findViewById(R.id.surface_camera);
        //mSurfaceView.setOnClickListener(this);

        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                camera.takePicture(null,mPictureCallback,mPictureCallback);
            }
        },6000);

        mSurfaceHolder=mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
    super.onRestoreInstanceState(savedInstanceState);
}
    Camera.PictureCallback mPictureCallback=new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // TODO Auto-generated method stub
            if(data!=null)
            {
                camera.stopPreview();
                mPreviewRunning=false;
                camera.release();
                try
                {
                    BitmapFactory.Options opts=new BitmapFactory.Options();
                    Bitmap bitmap=BitmapFactory.decodeByteArray(data,0,data.length,opts);
                    bitmap=Bitmap.createScaledBitmap(bitmap,480,480,false);
                    File file=new File(dir,"raj.jpg");
                    try
                    {
                        output=new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
                        output.flush();
                        output.close();
                        String url=Images.Media.insertImage(getContentResolver(),bitmap, "raj.jpg",null);
                    }
                    catch(Exception e)
                    {

                    }

                    ImgCap.image.setImageBitmap(bitmap);
                }
                catch (Exception e) {
                    // TODO: handle exception
                e.printStackTrace();
                }
                setResult(585);
                finish();           }

        }
    };




protected void onResume()
{
    Log.e(TAG,"onResume");
    super.onResume();
}
protected void onSaveInstanceState(Bundle outState)
{
    super.onSaveInstanceState(outState);
}
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.e(TAG,"surfaceChanged");
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.GINGERBREAD)
        {
        Camera.CameraInfo info=new Camera.CameraInfo();
        for(int i=0;i<Camera.getNumberOfCameras();i++)
        {
            Camera.getCameraInfo(i,info);
            if(info.facing==Camera.CameraInfo.CAMERA_FACING_FRONT)
            {
                camera=Camera.open(i);
            }
        }
        }
        if(camera==null)
        {
        camera=Camera.open();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
        if(mPreviewRunning)
        {
            camera.stopPreview();
        }
        Camera.Parameters p=camera.getParameters();
        p.setPreviewSize(width, height);
        camera.setParameters(p);
        try
        {
            camera.setPreviewDisplay(holder);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        camera.startPreview();
        mPreviewRunning=true;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.e(TAG,"surfaceDestroyed");
    }

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

    }
}

ImgCap.class

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class ImgCap extends Activity {
    public static ImageView image;
    private Button btn_camera;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        image = (ImageView) findViewById(R.id.image);
        btn_camera = (Button) findViewById(R.id.btn_camera);
        btn_camera.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent i = new Intent(ImgCap.this, CameraView.class);
                startActivityForResult(i, 999);

            }
});
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        if (requestCode == 999) {
            if (resultCode == 585) {

            } else {
                alert("Picture not Captured");
            }
        }
    }

    private void alert(String string) {
        // TODO Auto-generated method stub
        AlertDialog.Builder alert = new AlertDialog.Builder(ImgCap.this);
        alert.setMessage(string);
        alert.setTitle("Alert");
        alert.setNeutralButton("OK", null);
        alert.show();

    }

}

cameraview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
<SurfaceView  android:id="@+id/surface_camera"
    android:layout_width="fill_parent"
    android:layout_height="10dip"
    android:layout_weight="1"
    />    

</LinearLayout>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    相关资源
    最近更新 更多