与三星Galaxy S3,S4,S5的Andr​​oid相机/照片方向问题 [英] Android camera/picture orientation issues with Samsung Galaxy S3, S4, S5

查看:307
本文介绍了与三星Galaxy S3,S4,S5的Andr​​oid相机/照片方向问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发Android API 16至21摄像头应用程序,它主要和唯一的目的就是拿的纵向照片。我能够把几个设备(的Nexus 4,Nexus 5上,HTC ...)画面,并让他们正确的方向(即我的preVIEW等于拍摄的照片无论在规模和方向)。

I am developing a camera application for Android API 16 to 21 which main and only purpose is to take portrait photo. I am able to take picture with several devices (Nexus 4, Nexus 5, HTC...) and have them correctly oriented (meaning that my preview equals the taken picture both in size and orientation).

不过,我已经测试了几个其他的设备我的应用程序,其中一些是给我很多麻烦:三星Galaxy S3 / S4 / S5

However I have tested my application on several other devices and some of them are giving me alot of trouble: Samsung Galaxy S3/S4/S5.

在这三个设备上,preVIEW显示正常,但是该方法返回 onPictureTaken(最后一个字节[] JPEG,相机摄像头)图片总是横盘整理。

On these three devices, the preview is correctly displayed, however the pictures returned by the method onPictureTaken(final byte[] jpeg, Camera camera) are always sideways.

这是从创建位图的byte [] JPEG ,只是将其保存到磁盘之前显示在ImageView的给我的用户:

This is the Bitmap created from byte[] jpeg and displayed in the ImageView to my user just before saving it to the disk:

这是一次保存在磁盘上的图像:

And here is the image once saved on the disk:

正如你所看到的图像完全地伸展在preVIEW和磁盘上的错误旋转保存一次。

As you can see the image is completly stretched in the preview and wrongly rotated once saved on the disk.

下面是我的相机preVIEW类(我模糊的其他方法,因为他们一点关系都没有带摄像头参数):

Here is my CameraPreview class (I obfuscated other methods since they had nothing to do with camera parameters):

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
    private SurfaceHolder surfaceHolder;
    private Camera camera;

    // Removed unnecessary code

    public void surfaceCreated(SurfaceHolder holder)
    {
        camera.setPreviewDisplay(holder);
        setCameraParameters();
        camera.startPreview();
    }

    private void setCameraParameters()
    {
        Camera.Parameters parameters = camera.getParameters();
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);

        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(metrics);
        int rotation = windowManager.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 rotate = (info.orientation - degrees + 360) % 360;
        parameters.setRotation(rotate);

        // Save Parameters
        camera.setDisplayOrientation(90);
        camera.setParameters(parameters);
    }
}

除了三星的人们如何来code这一块确切适用于其他设备?

How come this exact piece of code works for other devices except Samsung's one ?

我试图找到以下SO职位,但没有答案可以帮助我至今:
<一href=\"http://stackoverflow.com/questions/15808719/controlling-the-camera-to-take-pictures-in-portrait-doesnt-rotate-the-final-ima\">this 之一和<一个href=\"http://stackoverflow.com/questions/19176038/camera-setdisplayorientation-function-is-not-working-for-samsung-galaxy-ace-wi\">this另外一个。

I tried to find answers on the following SO posts but nothing could help me so far: this one and this other one.

修改

实施乔伊冲的回答没有改变任何东西:

Implementing Joey Chong's answer does not changes anything:

public void onPictureTaken(final byte[] data, Camera camera)
{
    try
    {
        File pictureFile = new File(...);
        Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
        FileOutputStream fos = new FileOutputStream(pictureFile);
        realImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);

        int orientation = -1;
        ExifInterface exif = new ExifInterface(pictureFile.toString());
        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,  ExifInterface.ORIENTATION_NORMAL);

        switch (exifOrientation)
        {
            case ExifInterface.ORIENTATION_ROTATE_270:
                orientation = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                orientation = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                orientation = 90;
                break;
            case ExifInterface.ORIENTATION_NORMAL:
                orientation = 0;
                break;
            default:
                break;
        }

        fos.close();
}

下面是EXIF结果我得到一个工作装置:

Here are the EXIF results I get for a working device:


  • 方向:0

和这里的结果为S4:


  • 方向:0

推荐答案

这是因为手机还在景观保存,并把元数据为90度。
您可以尝试查看EXIF,旋转把之前在图像视图的位图。要检查EXIF,使用类似如下:
        INT方向= -1;

It is because the phone still save in landscape and put the meta data as 90 degree. You can try check the exif, rotate the bitmap before put in image view. To check exif, use something like below: int orientation = -1;

    ExifInterface exif = new ExifInterface(imagePath);

    int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
            ExifInterface.ORIENTATION_NORMAL);

    switch (exifOrientation) {
        case ExifInterface.ORIENTATION_ROTATE_270:
            orientation = 270;

            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            orientation = 180;

            break;
        case ExifInterface.ORIENTATION_ROTATE_90:
            orientation = 90;

            break;

        case ExifInterface.ORIENTATION_NORMAL:
            orientation = 0;

            break;
        default:
            break;
    }

这篇关于与三星Galaxy S3,S4,S5的Andr​​oid相机/照片方向问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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