android - 图像在android中自动旋转

标签 android titanium titanium-mobile

当我从相机拍摄照片并将其显示在 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 作为我的测试设备。

最佳答案

我会跟踪 this jira bug用于监控该问题的进展,尽管它自 2011 年以来一直开放,所以请不要屏住呼吸!

如果您不想等待数年才能修复,则必须为 Titanium 创建自定义 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;
}

关于android - 图像在android中自动旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23537545/

相关文章:

android - Android 虚拟设备中没有互联网

android - 以钛金属百分比定义字体大小

android - 使用 Titanium 检索用户的邮件

javascript - 使用 Titanium 的 RESTful 服务

titanium-mobile - 有没有办法覆盖 Titanium Appcelerator 中未处理的异常处理程序?

Titanium:如何在其选项卡中关闭 TabGroup?

android - 在预览屏幕中用 Titanium 裁剪图像

android - 在 Android 中正确实现 MVVM

android - 如何控制 MultiChoice AlertDialog

java - android中按钮的随机文本