【问题标题】:Image is auto-rotating in android图像在android中自动旋转
【发布时间】:2014-05-08 09:14:59
【问题描述】:

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

【问题讨论】:

  • 嗨 Swanand,你有没有找到解决方法,我正在处理同样的问题,请任何方向都非常感谢!!!

标签: android titanium titanium-mobile


【解决方案1】:

我会跟踪 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;
}

【讨论】:

    【解决方案2】:

    我有同样的pb,我这样做是为了解决它

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

    【讨论】:

    • 谢谢你的回答,我试试这个。
    【解决方案3】:

    我不太确定我是否完全理解您的问题(还没有处理过 androids 相机),但也许这可以帮助您? :) Android get Orientation of a camera Bitmap? And rotate back -90 degrees

    【讨论】:

      【解决方案4】:

      我知道问题所在,因为我也面临同样的问题。这是因为在某些设备制造商中设计相机的方式是将图像旋转 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 数据。
      【解决方案5】:

      这个问题似乎发生在 android

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

      【讨论】:

      • 在下面查看我的答案
      • @victor 我也认为这个问题只发生在 6.0 以下,但 autorotate 仍然对我不起作用:( .
      • @Swanand Strange,它对我有用。您可以发布您正在使用的 Titanium SDK 和 android 版本吗?最新的代码也会有所帮助。
      • @Victor 我的 SDK 是 5.2.2 并使用三星 s3。在 6.0.1 版本的 moto g3 上完美运行,而无需使用此属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多