我会跟踪这个Jira bug以监控问题的进展,尽管它自2011年以来一直处于开放状态,所以不要抱太大希望!
如果你不想等待多年才能修复,你将不得不为钛合金创建一个自定义的Android模块,以便正确地使其工作。以下是模块内容应该看起来像:
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
{
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) {
}
@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
{
int rotation = getRotation(filename);
imageFile = new File(convertPath(filename));
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);
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);
fileInputStream2 = new FileInputStream(imageFile);
scaledBitmap = BitmapFactory.decodeStream(fileInputStream2, null, opts);
Log.i(TAG, "Sampled image size: " + opts.outWidth + "x" + opts.outHeight);
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());
imageFile.delete();
Log.i(TAG, "Deleted old file");
imageFile.createNewFile();
Log.i(TAG, "Created 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 {
exif = new ExifInterface(filename);
property = exif.getAttribute(tag);
}
catch (IOException e)
{
property = "";
Log.e(TAG, "IO Exception occured, file probably does not exist.");
}
return property;
}
private String convertPath(String 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/");
}
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;
}