我尝试创建一个使用Intent拍摄照片并保存的应用程序(使用Unity3D)。
我的问题是保存图片然后检查其方向以便在需要时旋转它然后再次保存,这真的很长。
我认为这是因为我使用了太多工具。
您是否有一些减少处理时间的提示?
这是我的(编辑过的)代码,提前感谢:
package com.falsename.my;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
public class PhotoPlugin implements myAndroidPlugin
{
private boolean canTakePhotos;
private String mCurrentPhotoPath;
private static PhotoPlugin instance;
private myActivity activity;
private File photoFile;
static final int REQUEST_IMAGE_CAPTURE = 1;
private File createImageFile() throws IOException
{
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = this.activity.getExternalFilesDir(null);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent(myActivity a)
{
if(canTakePhotos)
{
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(a.getPackageManager()) != null) {
// Create the File where the photo should go
photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.e("my", ex.toString());
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
takePictureIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
a.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
}
public static void TakePicture()
{
instance.dispatchTakePictureIntent(instance.activity);
}
@Override
public void onActivityCreated(Context c, myActivity a)
{
instance = this;
this.activity = a;
canTakePhotos = a.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
@Override
public void onActivityResume(myActivity a) {
// TODO Auto-generated method stub
}
@Override
public void onActivityPause(myActivity a) {
}
@Override
public void onActivityNewIntent(myActivity a, Intent intent)
{
}
@Override
public void onActivityResult(myActivity a,
int requestCode, int resultCode, Intent data)
{
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE)
{
a.SendMessage("PhotoListener", "OnPhotoTaken", "");
PhotoPluginOrientationCheckerParams params = new PhotoPluginOrientationCheckerParams();
params.activity = a;
params.path = this.mCurrentPhotoPath;
params.file = this.photoFile;
new PhotoPluginOrientationChecker().execute(params);
}
}
}
和:
package com.falsename.my;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
public class PhotoPluginOrientationChecker extends AsyncTask<PhotoPluginOrientationCheckerParams, Void, Void>
{
myActivity a;
String path;
File file;
@Override
protected Void doInBackground(PhotoPluginOrientationCheckerParams ... params) {
a = params[0].activity;
path = params[0].path;
file = params[0].file;
try
{
ExifInterface ei = new ExifInterface(path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
SaveBitmap(RotateBitmap(getBitmapFromUri(a, Uri.fromFile(file)), 90));
break;
case ExifInterface.ORIENTATION_ROTATE_180:
SaveBitmap(RotateBitmap(getBitmapFromUri(a, Uri.fromFile(file)), 180));
break;
case ExifInterface.ORIENTATION_ROTATE_270:
SaveBitmap(RotateBitmap(getBitmapFromUri(a, Uri.fromFile(file)), 270));
break;
}
}
catch(IOException e)
{
Log.e("my", "Photo error");
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
a.SendMessage("PhotoListener", "OnPhotoSaved", path);
}
private void SaveBitmap(Bitmap bitmap)
{
FileOutputStream out = null;
try
{
out = new FileOutputStream(path);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (out != null)
{
out.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static Bitmap RotateBitmap(Bitmap source, float angle)
{
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
public Bitmap getBitmapFromUri(myActivity a, Uri imageUri)
{
ContentResolver cr = a.getContentResolver();
cr.notifyChange(imageUri, null);
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
with:
package com.falsename.my;
import java.io.File;
public class PhotoPluginOrientationCheckerParams
{
public myActivity activity;
public String path;
public File file;
}
答案 0 :(得分:1)
我找到的最佳解决方案:
如果最终图像计算时间很长,则缩放图像不会,但会向用户显示图片已被拍摄。
这是检查器代码(未清除但现在将执行):
package com.falsename.my;
import java.io.FileOutputStream;
import java.io.IOException;
import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.Matrix;
//import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
public class PhotoPluginOrientationChecker extends AsyncTask<PhotoPluginOrientationCheckerParams, Void, Void>
{
PhotoPluginOrientationCheckerParams params;
@Override
protected Void doInBackground(PhotoPluginOrientationCheckerParams ... params) {
this.params = params[0];
Log.v("my", "final mode");
if(this.params.highBitmap == null)
{
this.params.highBitmap = getBitmapFromUri(this.params.activity, Uri.fromFile(this.params.file));
this.params.angle = (this.params.highBitmap.getWidth() > this.params.highBitmap.getHeight()) ? 90 : 0;
}
Bitmap bmp = this.params.highBitmap;
String path = this.params.path;
if(this.params.low)
{
path += "_thumb.jpg";
bmp = HighToLowBitmap(bmp);
}
if(this.params.angle != 0)
{
Log.v("my", "rotate");
SaveBitmap(RotateBitmap(bmp, this.params.angle), path);
}
return null;
}
private static Bitmap HighToLowBitmap(Bitmap bmp)
{
return Bitmap.createScaledBitmap(bmp, bmp.getWidth() / 10, bmp.getHeight() / 10, true);
}
@Override
protected void onPostExecute(Void result)
{
Log.v("my", "OnPostExecute");
if(this.params.low)
{
this.params.low = false;
this.params.activity.SendMessage("PhotoListener", "OnThumbnailSaved", this.params.path + "_thumb.jpg");
new PhotoPluginOrientationChecker().execute(params);
}
else
{
this.params.activity.SendMessage("PhotoListener", "OnPhotoSaved", this.params.path);
}
}
private static void SaveBitmap(Bitmap bitmap, String path)
{
FileOutputStream out = null;
try
{
out = new FileOutputStream(path);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (out != null)
{
out.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static Bitmap RotateBitmap(Bitmap source, float angle)
{
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
public Bitmap getBitmapFromUri(myActivity a, Uri imageUri)
{
ContentResolver cr = a.getContentResolver();
cr.notifyChange(imageUri, null);
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
with:
package com.falsename.my;
import java.io.File;
import android.graphics.Bitmap;
public class PhotoPluginOrientationCheckerParams
{
public myActivity activity;
public String path;
public File file;
public boolean low = true;
public Bitmap highBitmap;
public int angle;
}