1

Android 版本 4.4.2 三星 Note 8:我使用表面视图制作了一个自定义相机。我可能能够捕获图像并将其存储在 SD 卡中。它在我检查过的所有设备上看起来都很完美,例如 Nexus 7、Micromax Turbo、Canvas Hd、Moto G、Moto E。

但是在 samsung Note 8(4.4.2 - Kitkat) 中,图像得到了 1/8 次平铺。有时是 2/8。

当用户捕获照片并将其存储在 SdCard 文件夹中时,它包含平铺图像。像这样: http: //prntscr.com/5xoc5e

在此处输入图像描述

摄像头采集代码:

OnCapture 按钮单击:

camera.takePicture(null, null, mPicture);
PictureCallback mPicture = new PictureCallback()
    {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) 
        {
            mrawDataCapturedImg = data;

                    try
                    {
                      BitmapFactory.Options options = new BitmapFactory.Options();
                      options.inSampleSize = 2;
                      Bitmap bmp = BitmapFactory.decodeByteArray(mrawDataCapturedImg, 0, mrawDataCapturedImg.length,options);
                      mimgPreview.setImageBitmap(bmp);
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
        }
    };

存储图像代码:

 File pictureFile = new File(mediaStorageDir.getPath() 
        + File.separator + saveName + ".jpg");

try
{
    FileOutputStream fos = new FileOutputStream(pictureFile);
    fos.write(mrawDataCapturedImg);
    fos.close();
}
catch (FileNotFoundException e)
{
    e.printStackTrace();
} 
catch (IOException e)
{
    e.printStackTrace();
}

MyCameraPreview 类:

public class MyCameraPreview extends SurfaceView implements SurfaceHolder.Callback 
{
    private SurfaceHolder mSurfaceHolder;
    private Camera mCamera;
    PreviewCallback mPreviewCallback;
    AutoFocusCallback mAutoFocusCallback;
    @SuppressWarnings("unused")
    private String TAG = "camera";
    private Activity context; 
    Size mPreviewSize;
    List<Size> mSupportedPreviewSizes;

    @SuppressWarnings("deprecation")
    public MyCameraPreview(Activity context, Camera camera, AutoFocusCallback autoFocusCB,PreviewCallback previewCallback) 
    {
        super(context);

        mPreviewCallback = previewCallback;
        this.context = context;
        this.mCamera = camera;
        mAutoFocusCallback = autoFocusCB;
        this.mSurfaceHolder = MyCameraPreview.this.getHolder();
        this.mSurfaceHolder.addCallback(MyCameraPreview.this);
        this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) 
    {
        try 
        {
            if(mCamera!=null)
            {
                // Now that the size is known, set up the camera parameters and begin
                // the preview.
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
                mCamera.setParameters(parameters);

                setCameraDisplayOrientation(0, mCamera);
                mCamera.setPreviewDisplay(surfaceHolder);
                mCamera.setPreviewCallback(mPreviewCallback);
                mCamera.startPreview();
                mCamera.autoFocus(mAutoFocusCallback);
            }

        }
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) 
    {
         try {
                if (mCamera != null) 
                {
                    mCamera.setPreviewDisplay(surfaceHolder);
                }
            } catch (IOException exception) {
                Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
            }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) 
    {
        if (mCamera != null) 
        {
            if(mAutoFocusCallback != null)
            mCamera.cancelAutoFocus();
            mCamera.stopPreview();
        }
    }

    public void setCameraDisplayOrientation(
             int cameraId, android.hardware.Camera camera) 
    {
         android.hardware.Camera.CameraInfo info =
                 new android.hardware.Camera.CameraInfo();
         android.hardware.Camera.getCameraInfo(cameraId, info);
         int rotation = context.getWindowManager().getDefaultDisplay()
                 .getRotation();
         int degrees = 0;
         switch (rotation) 
         {
             case Surface.ROTATION_0: degrees = 0; break;
             case Surface.ROTATION_90: degrees = 90; break;
             case Surface.ROTATION_180: degrees = 180; break;
             case Surface.ROTATION_270: degrees = 270; break;
         }

         int result;
         if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
             result = (info.orientation + degrees) % 360;
             result = (360 - result) % 360;  // compensate the mirror
         } else {  // back-facing
             result = (info.orientation - degrees + 360) % 360;
         }
         camera.setDisplayOrientation(result);
     }

    public void setCamera(Camera camera) 
    {
        mCamera = camera;
        if (mCamera != null) 
        {
            mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    {
        // We purposely disregard child measurements because act as a
        // wrapper to a SurfaceView that centers the camera preview instead
        // of stretching it.
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);

        if (mSupportedPreviewSizes != null) 
        {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }
    }

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) 
    {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

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

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (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);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) 
        {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes)
            {
                if (Math.abs(size.height - targetHeight) < minDiff)
                {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

}
4

0 回答 0