【问题标题】:android custom camera orientationandroid自定义相机方向
【发布时间】:2014-10-28 19:58:38
【问题描述】:

我已经定义了一个自定义的camera view 来拍照。我遇到的问题是,如果照片是用portrait 中的相机拍摄的,图像会在90 degree 中旋转。我想像 Instagram 相机一样做同样的事情。 我想要的是,如果我以任何角度旋转相机,我希望位图位于Portrait 并保存到设备。

请帮帮我。

这是我的代码:

 private PictureCallback mPicture = new PictureCallback() {

    public void onPictureTaken(byte[] data, Camera camera) {

        safeToTakePicture = true;

        File pictureFile = new File(Common.FILE_IMAGE_STORAGE, filename);

        if (pictureFile.exists()) {
            pictureFile.delete();
        }

        try {
            FileOutputStream purge = new FileOutputStream(pictureFile);
            purge.write(data);
            purge.close();
        } catch (FileNotFoundException e) {
                } 
          catch (IOException e) {
        }

        if (data != null) {

            new AsyncBitmapCreation(filepath).execute();
        }
    }
};

 class AsyncBitmapCreation extends AsyncTask<Void, Void, Bitmap> {

    byte[] data;

    public AsyncBitmapCreation(byte[] data) {
        this.data = data;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {

        return rotateImage(data);
    }

    @Override
    protected void onPostExecute(Bitmap result) {

        bitmap = result;

    }

}

在 Rotate 函数中我再次使用 ExifInterface

 private Bitmap rotateImage(final byte[] data) {
    Bitmap scaledBitmap = null;

    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 3;

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

        int actualHeight = bmp.getHeight();
        int actualWidth = bmp.getWidth();

        float maxHeight = 1020.0f;
        float maxWidth = 680.0f;
        float imgRatio = actualWidth / actualHeight;
        float maxRatio = maxWidth / maxHeight;

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }

        options.inSampleSize = calculateInSampleSize(options, actualWidth,
                actualHeight);

        // inJustDecodeBounds set to false to load the actual bitmap
        options.inJustDecodeBounds = false;

        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {

            Bitmap.Config conf = Bitmap.Config.ARGB_8888;
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,
                    conf);

        } catch (OutOfMemoryError exception) {

        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);

        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2,
                middleY - bmp.getHeight() / 2, new Paint(
                        Paint.FILTER_BITMAP_FLAG));

        ExifInterface exif;
        try {

            exif = new ExifInterface(fileUri.getPath());
            Matrix matrix = new Matrix();
            if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("6")) {
                matrix.postRotate(90);
            } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("8")) {
                matrix.postRotate(270);

            } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("3")) {
                matrix.postRotate(180);
            } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("0")) {
                matrix.postRotate(90);

            }

            scaledBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
                    bmp.getHeight(), matrix, true);

        } catch (IOException e) {

        }

    } catch (Exception e) {

    }

    return scaledBitmap;

}

Surfaceview 和回调参考这个链接 Android Camera setDisplayOrientation does not work

 public class PreviewCamera extends SurfaceView implements
    SurfaceHolder.Callback {

private SurfaceHolder mHolder;
private Camera mCamera;

private static boolean DEBUGGING = true;
private static final String LOG_TAG = "CameraPreviewSample";
private static final String CAMERA_PARAM_ORIENTATION = "orientation";
private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
private static final String CAMERA_PARAM_PORTRAIT = "portrait";
protected Activity mActivity;

protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;

public PreviewCamera(Context context, Camera camera) {
    super(context);
    mActivity = (Activity) context;
    mCamera = camera;
    mHolder = getHolder();
    mHolder.addCallback(this);
    // deprecated setting, but required on Android versions prior to 3.0
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}

@Override
public void surfaceCreated(SurfaceHolder holder) {

    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    } catch (IOException e) {
        Log.d("CameraView",
                "Error setting camera preview: " + e.getMessage());
    }

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    if (mHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }

    // stop preview before making changes
    try {
        // mCamera.stopPreview();
    } catch (Exception e) {
        // ignore: tried to stop a non-existent preview
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here

    // start preview with new settings
    try {
        Camera.Parameters cameraParams = mCamera.getParameters();
        boolean portrait = isPortrait();
        configureCameraParameters(cameraParams, portrait);

        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

    } catch (Exception e) {
        Log.d("CameraView",
                "Error starting camera preview: " + e.getMessage());
    }

}

public void onPause() {
    mCamera.release();
    mCamera = null;
}

protected void configureCameraParameters(Camera.Parameters cameraParams,
        boolean portrait) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and
                                                                // before
        if (portrait) {
            cameraParams.set(CAMERA_PARAM_ORIENTATION,
                    CAMERA_PARAM_PORTRAIT);
        } else {
            cameraParams.set(CAMERA_PARAM_ORIENTATION,
                    CAMERA_PARAM_LANDSCAPE);
        }
    } else { // for 2.2 and later
        int angle;
        Display display = mActivity.getWindowManager().getDefaultDisplay();
        switch (display.getRotation()) {
        case Surface.ROTATION_0: // This is display orientation
            angle = 90; // This is camera orientation
            break;
        case Surface.ROTATION_90:
            angle = 0;
            break;
        case Surface.ROTATION_180:
            angle = 270;
            break;
        case Surface.ROTATION_270:
            angle = 180;
            break;
        default:
            angle = 90;
            break;
        }
        Log.v(LOG_TAG, "angle: " + angle);
        //mCamera.setDisplayOrientation(angle);
          mCamera.setDisplayOrientation(90);
    }

    cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
    cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
    if (DEBUGGING) {
        Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width
                + ", h: " + mPreviewSize.height);
        Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width
                + ", h: " + mPictureSize.height);
    }

    mCamera.setParameters(cameraParams);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub

}

public boolean isPortrait() {
    return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}

}

【问题讨论】:

    标签: android android-camera


    【解决方案1】:

    您好,使用此代码对您有帮助...如果您需要帮助,请告诉我。

     public void takePhoto() {
    
                Intent intent = new Intent(
                        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                File folder = new File(Environment.getExternalStorageDirectory() + "/"
                        + getResources().getString(R.string.app_name));
    
                if (!folder.exists()) {
                    folder.mkdir();
                }
                final Calendar c = Calendar.getInstance();
                String new_Date = c.get(Calendar.DAY_OF_MONTH) + "-"
                        + ((c.get(Calendar.MONTH)) + 1) + "-" + c.get(Calendar.YEAR)
                        + " " + c.get(Calendar.HOUR) + "-" + c.get(Calendar.MINUTE)
                        + "-" + c.get(Calendar.SECOND);
                imageUrl = String.format(
                        Environment.getExternalStorageDirectory() + "/"
                                + getResources().getString(R.string.app_name)
                                + "/%s.png", "Accident_Info(" + new_Date + ")");
                File photo = new File(imageUrl);
                intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                intent.putExtra("exit", "false");
                intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
                        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
    
                AccidentInfo.this.startActivityForResult(intent, CAMERA_PIC_REQUEST);
            }
    
    
    private Bitmap callTempMethod(String tempPath) {
            if (tempPath != null) {
                Uri selectedImage = Uri.parse(tempPath);
                if (!TextUtils.isEmpty(tempPath)) {
                    LogMessage.i(TAG, "LLLpath::" + tempPath);
                    File file = new File(tempPath);
                    if (selectedImage.toString().startsWith("content")) {
                        return DealershipApplication.decodeStrem(file,
                                selectedImage, mContext);
                    } else {
                        if (!file.isDirectory()) {
                            return DealershipApplication.decodeFile(file, 10, 0);
                        } else {
                            return null;
                        }
                    }
                } else
                    return null;
            } else {
                return null;
            }
        }
    
    
    public static int calculateInSampleSize(BitmapFactory.Options options,
                int reqWidth, int reqHeight) {
            // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
    
            if (height > reqHeight || width > reqWidth) {
                final int heightRatio = Math.round((float) height
                        / (float) reqHeight);
                final int widthRatio = Math.round((float) width / (float) reqWidth);
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }
    
            return inSampleSize;
        }
    
    
    public static Bitmap getSampleBitmapFromFile(String bitmapFilePath,
                int reqWidth, int reqHeight) throws FileNotFoundException {
            // calculating image size
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(
                    new FileInputStream(new File(bitmapFilePath)), null, options);
    
            int scale = calculateInSampleSize(options, reqWidth, reqHeight);
    
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
    
            return BitmapFactory.decodeStream(new FileInputStream(new File(
                    bitmapFilePath)), null, o2);
        }
    

    当您拍摄照片时,它会以爱国者模式保存。请根据您的需要更改此代码。谢谢。

    【讨论】:

    • 如果此代码不适合您,请告诉我。我会以其他方式帮助你。
    • 你能给我推荐一个surfaceview的例子吗
    • 现在我已经更新了所有类。检查一下...根据您的需要使用代码。
    • 我没有使用 Intent,我使用的是surfaceview和camerapreview
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多