如何旋转和翻转的位图中onPictureTaken [英] How to rotate and flip bitmap in onPictureTaken

查看:328
本文介绍了如何旋转和翻转的位图中onPictureTaken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现在 onPictureTaken 拯救了位图镜像关于y轴,顺时针旋转90度,即使相机preVIEW没有。这是上的运行2.3.6我的Nexus S。在我的Nexus 4运行具有4.2相同的程序已生成位图镜像绕y轴和顺时针方向旋转180度。

I'm finding in onPictureTaken that the bitmap saved is mirrored about the y-axis and rotated 90 degrees clockwise even though the camera preview was not. This is on my Nexus S that's running 2.3.6. The same program running on my Nexus 4 with 4.2 has the resulting bitmap mirrored about the y-axis and rotated 180 degrees clockwise.

这是在code,我在跑 onPictureTaken

This is the code I'm running in onPictureTaken:

@Override
public void onPictureTaken(final byte[] data, Camera camera) {
    Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
    String path = MediaStore.Images.Media.insertImage(getContentResolver(), picture, "name" , "description");
    Log.e("tag", "path: " + path); // prints something like "path: content://media/external/images/media/819"

    try {
        ExifInterface exif = new ExifInterface(path); // prints this error: "04-25 21:28:21.063: E/JHEAD(12201): can't open 'content://media/external/images/media/819'"
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        Log.e("tag", "exif orientation: " + orientation); // this is outputting orientation unknown
    } catch (IOException e) {
        e.printStackTrace();
    }
}

谁能告诉我怎么我纠正这个因为我似乎得到来自不同设备的不同的结果?如何检测所生成位图的方向,使我认识到旋转或者90度或180度逆时针?

Can anyone show me how I rectify this given that I seem to be getting different results from different devices? How do I detect the orientation of the resulting bitmap so that I know to rotate it either 90 or 180 degrees counterclockwise?

我添加使用ExifInterface的东西,我一直在阅读有关更多的信息,但这些信息似乎并没有泛出...

I added some more information using the ExifInterface stuff I've been reading about, but that information doesn't seem to pan out...

推荐答案

我已经投入了大量的工作,这个和思想,我想分享我的解决方案。 这是对摩托罗拉Devy,三星Xcover 1和三星XCover 2测试。

I have put a lot of work into this and thought, I'd share my solution. It is tested on a Motorola Devy, Samsung Xcover 1 and Samsung XCover 2.

当我和一个自定义的摄像头preVIEW工作,该解决方案主要有两个 部分。 1.小心的摄像头preVIEW和的preVIEW设置旋转根据 到设备的旋转。 2.一旦拍摄照片时,那就是onPictureTaken'回调函数 旋转图片以正确的角度,这样它显示了在preVIEW刚 显示。

As I work with a custom camera preview, the solution basically has two parts. 1. Take care of the camera preview and set rotation of the preview according to device rotation. 2. Once a picture is taken, that is the 'onPictureTaken' callback is invoked rotate the picture by the correct angle, such that it shows what the preview just showed.

private void initPreview(int width, int height) {
    if (camera != null && holder.getSurface() != null) {
        try {
            camera.setPreviewDisplay(holder);
        } catch (Throwable t) {
            Log.e("PreviewDemo-surfaceCallback",
              "Exception in setPreviewDisplay()", t);
            Toast.makeText(getContext(), t.getMessage(),
                       Toast.LENGTH_LONG).show();
        }

        try {
            Camera.Parameters parameters=camera.getParameters();

            Camera.Size size=getBestPreviewSize(width, height, parameters);
            Camera.Size pictureSize=getSmallestPictureSize(parameters);

            Display display = windowManager.getDefaultDisplay();
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
                if (isPortrait(display)) {
                    parameters.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
                } else {
                    parameters.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
                }
            } else { // for 2.2 and later
                switch (display.getRotation()) {
                    case Surface.ROTATION_0: // This is display orientation
                        if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
                        else parameters.setPreviewSize(size.width, size.height);
                        camera.setDisplayOrientation(90);
                        break;
                    case Surface.ROTATION_90:
                        if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
                        else parameters.setPreviewSize(size.width, size.height);
                        camera.setDisplayOrientation(0);
                        break;
                    case Surface.ROTATION_180:
                        if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
                        else parameters.setPreviewSize(size.width, size.height);
                        camera.setDisplayOrientation(270);
                        break;
                    case Surface.ROTATION_270:
                        if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
                        else parameters.setPreviewSize(size.width, size.height);
                        camera.setDisplayOrientation(180);
                        break;
                }
            }

            parameters.setPictureSize(pictureSize.width, pictureSize.height);
            //parameters.setPictureFormat(ImageFormat.JPEG);
            camera.setParameters(parameters);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


您'surfaceChanged的方法,在你的相机preVIEW(SurfaceView) 你应该是这样的:


Your 'surfaceChanged' method, in your camera preview (SurfaceView), you should look like this:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    stopPreview();
    initPreview(w, h);
    startPreview();
}


其中


where

停止preVIEW:

private void stopPreview() {
    if (camera != null) {
        camera.stopPreview();
    }
}

开始preVIEW:

startPreview:

private void startPreview() {
    if (camera != null) {
        camera.startPreview();
    }
}

2


在您的onPictureTaken回调旋转图片,使用下面的code:

2


In your 'onPictureTaken' callback rotate the picture, using the following code:

Display display = getWindowManager().getDefaultDisplay();
int rotation = 0;
switch (display.getRotation()) {
    case Surface.ROTATION_0: // This is display orientation
    rotation = 90;
    break;
case Surface.ROTATION_90:
    rotation = 0;
    break;
case Surface.ROTATION_180:
    rotation = 270;
    break;
case Surface.ROTATION_270:
    rotation = 180;
        break;
 }

 Bitmap bitmap = ImageTools.toBitmap(data);
 bitmap = ImageTools.rotate(bitmap, rotation);


其中


where

ImageTools.toBitmap =

ImageTools.toBitmap =

public static Bitmap toBitmap(byte[] data) {
    return BitmapFactory.decodeByteArray(data , 0, data.length);
}


ImageTools.rotate =


ImageTools.rotate =

public static Bitmap rotate(Bitmap in, int angle) {
    Matrix mat = new Matrix();
    mat.postRotate(angle);
    return Bitmap.createBitmap(in, 0, 0, in.getWidth(), in.getHeight(), mat, true);
}

这篇关于如何旋转和翻转的位图中onPictureTaken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆