在安卓系统中,图片自动旋转了。

3
当我从相机拍照并在ImageView中显示时,它会自动逆时针旋转90度。如何使竖向的图像仍然以竖向模式显示,横向的图像以横向模式显示在ImageView中。谢谢。
这是我的代码:
Titanium.Media.showCamera({
    success : function(event) {
        imageHeight = event.media.height;
        imageWidth = event.media.width;
        var blob = event.media;

        ImageView.image = blob;

        lblWidth.text = 'W :'+imageWidth;
        lblHeight.text ='H :'+imageHeight;
    },
    cancel : function() {
    },
    error : function(error) {
    },
    saveToPhotoGallery : true,
    allowEditing : true,
    mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO]
});

我正在使用三星Galaxy S4作为我的测试设备。


1
嗨Swanand,你有没有找到解决方法?我也遇到了同样的问题,请指点一下,非常感谢!!! - TheFuquan
5个回答

1

我会跟踪这个Jira bug以监控问题的进展,尽管它自2011年以来一直处于开放状态,所以不要抱太大希望!

如果你不想等待多年才能修复,你将不得不为钛合金创建一个自定义的Android模块,以便正确地使其工作。以下是模块内容应该看起来像:

/**
 * This file was auto-generated by the Titanium Module SDK helper for Android
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 * the solution for ImageFactoryModule was coming from this ticket
 * https://jira.appcelerator.org/browse/TIMOB-3427
 * https://github.com/freshheads/fh.imagefactory
 */
package com.company.utils;

import java.util.HashMap;
import java.util.Map;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollModule;
import org.appcelerator.kroll.annotations.Kroll;

import org.appcelerator.titanium.TiApplication;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.util.TiConvert;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;

@Kroll.module(name="Utils", id="com.company.utils")
public class UtilsModule extends KrollModule
{
    // Standard Debugging variables
    private static final String TAG = "com.company.utils";

    @Kroll.constant public static final String TAG_ORIENTATION = ExifInterface.TAG_ORIENTATION;
    @Kroll.constant public static final int ORIENTATION_ROTATE_180 = ExifInterface.ORIENTATION_ROTATE_180;
    @Kroll.constant public static final int ORIENTATION_ROTATE_270 = ExifInterface.ORIENTATION_ROTATE_270;
    @Kroll.constant public static final int ORIENTATION_ROTATE_90 = ExifInterface.ORIENTATION_ROTATE_90;

    public UtilsModule() {
        super();
    }

    @Kroll.onAppCreate
    public static void onAppCreate(TiApplication app) {
    }

    // Methods
    /**
     * Auto rotate and resize to the desired maximum size keeping aspect
     *
     * @param filename
     * @param size
     * @param quality
     * @return
     */
    @Kroll.method
    public Boolean rotateResizeImage(String filename, int size, int quality)
    {
        Log.i(TAG, "In rotateResizeImage");
        File imageFile = null;
        FileInputStream fileInputStream = null;
        FileInputStream fileInputStream2 = null;
        FileOutputStream fileOutputStream = null;
        Bitmap scaledBitmap = null;
        Bitmap resizedBitmap = null;
        try
        {
            // Determine the orientation
            int rotation = getRotation(filename);

            // Read the file path into a File
            imageFile = new File(convertPath(filename));

            // Decode once to determine size
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            fileInputStream = new FileInputStream(imageFile);
            BitmapFactory.decodeStream(fileInputStream, null, opts);
            Log.i(TAG, "Original image size: " + opts.outWidth + "x" + opts.outHeight);

            // Determine scaling based on size
            int sample = 1;
            while (opts.outWidth / sample / 2 >= size || opts.outHeight / sample / 2 >= size) {
                sample *= 2;
            }
            opts = new BitmapFactory.Options();
            opts.inSampleSize = sample;
            Log.i(TAG, "Sample size: " + sample);

            // Decode with scaling applied to save a huge amount of memory
            fileInputStream2 = new FileInputStream(imageFile);
            scaledBitmap = BitmapFactory.decodeStream(fileInputStream2, null, opts);
            Log.i(TAG, "Sampled image size: " + opts.outWidth + "x" + opts.outHeight);

            // Create the appropriate Matrix to resize and rotate then create Bitmap
            float scale = (float)size / (float)(opts.outWidth > opts.outHeight ? opts.outWidth : opts.outHeight);
            Matrix matrix = new Matrix();
            matrix.postRotate(rotation);
            matrix.postScale(scale, scale);
            resizedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, (int)scaledBitmap.getWidth(), (int)scaledBitmap.getHeight(), matrix, true);
            Log.i(TAG, "Scaled image size: " + resizedBitmap.getWidth() + "x" + resizedBitmap.getHeight());

            // Delete old file
            imageFile.delete();
            Log.i(TAG,  "Deleted old file");

            // Create new file
            imageFile.createNewFile();
            Log.i(TAG,  "Created new file");

            // Copy rotated, resized image to new file
            fileOutputStream = new FileOutputStream(imageFile);
            resizedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream);
            fileOutputStream.flush();
            Log.i(TAG,  "Copied rotated, resized image to new file");

            return true;
        }
        catch (Exception e)
        {
            Log.e(TAG, "ERROR: " + e.toString());
            return false;
        }
        finally {
            if(imageFile != null) {
                imageFile = null;
            }
            if(fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                }
                fileInputStream = null;
            }
            if(fileInputStream2 != null) {
                try {
                    fileInputStream2.close();
                } catch (IOException e) {
                }
                fileInputStream2 = null;
            }
            if(fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                }
                fileOutputStream = null;
            }
            if(scaledBitmap != null) {
                scaledBitmap.recycle();
                scaledBitmap = null;
            }
            if(resizedBitmap != null) {
                resizedBitmap.recycle();
                resizedBitmap = null;
            }
        }
    }

    private Integer getRotation(String filename) {
        int orientation = TiConvert.toInt(getExifTag(filename, TAG_ORIENTATION));
        Log.i(TAG, "Detected orientation: " + orientation);
        int rotation = 0;
        switch (orientation)
        {
            case ORIENTATION_ROTATE_90:
                rotation = 90;
                break;

            case ORIENTATION_ROTATE_180:
                rotation = 180;
                break;

            case ORIENTATION_ROTATE_270:
                rotation = 270;
                break;
        }
        Log.i(TAG, "Determined rotation: " + rotation);
        return rotation;
    }

    private String getExifTag(String filename, String tag)
    {
        String property = "";
        ExifInterface exif;
        filename = convertPath(filename);
        try {
            //Log.i(TAG, "Read Exif tag: " + tag + ", from file: " + filename);
            exif = new ExifInterface(filename);
            property = exif.getAttribute(tag);
            //Log.i(TAG, "Exif tag value: " + property);
        }
        catch (IOException e)
        {
            property = "";
            Log.e(TAG, "IO Exception occured, file probably does not exist.");
        }
        return property;
    }

    private String convertPath(String path)
    {
        //Log.i(TAG, "Open FileInputStream for path: " + path);
        if (path.startsWith("file://") || path.startsWith("content://") || path.startsWith("appdata://") || path.startsWith("appdata-private://"))
        {
            path = path.replaceAll("file://", "");
            path = path.replaceAll("content://", "");
            path = path.replaceAll("appdata:///?", "/mnt/sdcard/" + TiApplication.getInstance().getPackageName() + "/");
            path = path.replaceAll("appdata-private:///?", "/data/data/" + TiApplication.getInstance().getPackageName() + "/app_appdata/");
            //Log.i(TAG, "Converted path to: " + path);
        }
        return path;
    }
}

以下是在您的Titanium应用程序中如何使用它,只需在拍照后传递e.media即可:

function rotateAndResize (media, width, quality) {
    var utilsModule = require('com.company.utils');

    // Create file to store photo.
    var dataDirectory = Ti.Filesystem.getApplicationDataDirectory();
    var fileName = String.format('Company_Photo_%s.jpg', moment().format('YYYY-MM-DD-HH-mm-ss-SSS-ZZ'));
    var file = Ti.Filesystem.getFile(dataDirectory, fileName);
    var fileNativePath = file.nativePath;

    // Write media to file.
    file.write(media);
    file = null;

    // Rotate photo in file, resize, and adjust quality.
    utilsModule.rotateResizeImage(fileNativePath, width || 640, quality || 80);

    // Get new and improved media out of file.
    media = Ti.Filesystem.getFile(fileNativePath);

    return media;
}

1

我有同样的问题,我这样解决它

var photo = event.media;
if (OS_ANDROID) {
    photo = photo.imageAsResized(photo.width, photo.height);
}
imageView.image = photo;

谢谢你的回答,我会尝试这个方法。 - Swanand

0

看起来这个问题发生在Android版本低于6.0的设备上。您可以尝试在创建ImageView时将'autorotate: true'设置为true(此属性标记为“仅限创建”)。

var photoView = Ti.UI.createImageView({
    image : event.media,
    autorotate: true,
});

请检查下面的答案 - Said CHAOUCHE
@victor 我也认为这个问题只会在6.0以下版本出现,但是自动旋转对我仍然没有起作用 :(。 - Swanand
@Swanand,对我来说它是能够运行的。你可以发一下你使用的Titanium SDK和Android版本吗?最新的代码也会有帮助。 - Victor
@Victor 我的 SDK 版本是 5.2.2,使用三星 S3 手机。在 Moto G3 上工作完美,且不需要使用这个属性。 - Swanand

0

我知道这个问题,因为我曾经面临同样的情况。这是因为一些设备制造商将相机设计成以90度旋转的方式拍摄图像,不确定如何在Titanium中解决,但我已经在Java中解决了这个问题。

public static Bitmap getCorrectBitmap(Bitmap bitmap, String filePath) {
        ExifInterface ei;
        try {
            ei = new ExifInterface(filePath);

            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);

            switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                return rotateImage(bitmap, 90);

            case ExifInterface.ORIENTATION_ROTATE_180:
                return rotateImage(bitmap, 180);

            case ExifInterface.ORIENTATION_ROTATE_270:
                return rotateImage(bitmap, 270);

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bitmap;
    }

希望这能有所帮助。

Titanium没有提供任何API来获取“Exif”数据。 - Swanand

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接