android自定义相机方向

时间:2014-10-28 09:54:46

标签: android android-camera

我已经定义了一个自定义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;

    }

}

这里的旋转功能我再次使用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);
}

}

1 个答案:

答案 0 :(得分:0)

您好使用此代码它会帮助您...告诉我您是否需要帮助。

 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);
    }

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