Android Dev: создание растрового изображения из временного файла, хранящегося на SD-карте, настройка ImageView, а затем его локальное сохранение
Таким образом, из-за проблем с качеством, возникающих при получении данных из android.media.action.IMAGE_CAPTURE, мне, очевидно, нужно было вызвать действие, сохранить локальный временный файл, из которого я мог бы создать растровое изображение. Это растровое изображение будет обрезано в квадрат, установлено в ImageView, а затем сохранено локально; Однако у меня есть некоторые проблемы. Все (кроме обрезки на данный момент) работает до установки изображения (возвращает пустое изображение) и его внутреннего хранения, после чего происходит сбой. Я пытаюсь найти файл на SD-карте с помощью файлового менеджера, но папка даже не отображается, поэтому я не знаю, действительно ли файл создается. Есть идеи, что я делаю не так? Код:
private static final String TAG = "AddEdit";
private final static String FOLDER_NAME = "com.ex.beerlog/Image/";
private Uri selectedImageUri = null;
private final static int CAPTURE_IMAGE_CALLBACK = 1;
switch (arg0.getId()) {
case R.id.imageView1:
File photo = null;
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
photo = new File(android.os.Environment.getExternalStorageDirectory(), FOLDER_NAME + File.separator
+ "temp.png");
Log.w(TAG, "*******Photo path set from Enviro*********");
} else {
photo = new File(getCacheDir(), FOLDER_NAME + File.separator + "temp.png");
Log.w(TAG, "*******photo set from cache*********");
}
if (photo != null) {
Log.w(TAG, "*******Photo is not null*********");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
selectedImageUri = Uri.fromFile(photo);
Log.w(TAG, "*******from imageUri=" + selectedImageUri + "*********");
startActivityForResult(intent, CAPTURE_IMAGE_CALLBACK);
}
break;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CAPTURE_IMAGE_CALLBACK:
if (resultCode == RESULT_OK) {
String path = selectedImageUri.toString();
Log.w(TAG, "*****path set =" + path + "******");
BitmapFactory.Options options = new BitmapFactory.Options();
Log.w(TAG, "*****Bimapfactory options set******");
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Log.w(TAG, "****Options defined********");
bmp = BitmapFactory.decodeFile(path, options);
Log.w(TAG, "*****Bmp is set ==> crop******");
brewPhoto.setImageBitmap(bmp);
Log.w(TAG, "******************Image is set to ButtonImage**********************");
// Store image
FileOutputStream fos;
Log.w(TAG, "********FileOutPutStream created*************");
try {
fos = openFileOutput(cDate, Context.MODE_PRIVATE);
Log.w(TAG, "********FileOutPutStream defined*************");
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
Log.w(TAG, "********bitmap compressed*************");
fos.close();
Log.w(TAG, "*****FOS closed**********");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
Вот журнал ошибок, который я получаю:
03-18 21:24:50.325: W/AddEdit(8208): *****path set =file:///storage/sdcard0/com.ex.beerlog/Image/temp.png******
03-18 21:24:50.325: W/AddEdit(8208): *****Bimapfactory options set******
03-18 21:24:50.325: W/AddEdit(8208): ****Options defined********
03-18 21:24:50.325: I/System.out(8208): Not a DRM File, opening notmally
03-18 21:24:50.325: W/AddEdit(8208): *****Bmp is set ==> crop******
03-18 21:24:50.325: W/AddEdit(8208): ******************Image is set to ButtonImage**********************
03-18 21:24:50.325: W/AddEdit(8208): ********FileOutPutStream created*************
03-18 21:24:50.325: W/AddEdit(8208): ********FileOutPutStream defined*************
03-18 21:24:50.335: W/dalvikvm(8208): threadid=1: thread exiting with uncaught exception (group=0x41314438)
03-18 21:24:50.335: E/AndroidRuntime(8208): FATAL EXCEPTION: main
03-18 21:24:50.335: E/AndroidRuntime(8208): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.ex.beerlog/com.ex.beerlog.AddEdit}: java.lang.NullPointerException
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.ActivityThread.deliverResults(ActivityThread.java:3183)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3226)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.ActivityThread.access$1200(ActivityThread.java:139)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.os.Handler.dispatchMessage(Handler.java:99)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.os.Looper.loop(Looper.java:137)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.ActivityThread.main(ActivityThread.java:4918)
03-18 21:24:50.335: E/AndroidRuntime(8208): at java.lang.reflect.Method.invokeNative(Native Method)
03-18 21:24:50.335: E/AndroidRuntime(8208): at java.lang.reflect.Method.invoke(Method.java:511)
03-18 21:24:50.335: E/AndroidRuntime(8208): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
03-18 21:24:50.335: E/AndroidRuntime(8208): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
03-18 21:24:50.335: E/AndroidRuntime(8208): at dalvik.system.NativeStart.main(Native Method)
03-18 21:24:50.335: E/AndroidRuntime(8208): Caused by: java.lang.NullPointerException
03-18 21:24:50.335: E/AndroidRuntime(8208): at com.ex.beerlog.AddEdit.onActivityResult(AddEdit.java:329)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.Activity.dispatchActivityResult(Activity.java:5232)
03-18 21:24:50.335: E/AndroidRuntime(8208): at android.app.ActivityThread.deliverResults(ActivityThread.java:3179)
03-18 21:24:50.335: E/AndroidRuntime(8208): ... 11 more
Итак, как вы можете видеть, fileInputSteam создан, но вылетает при попытке сохранить изображение. Я удалил этот сегмент кода, и изображение, которое устанавливается в ImageView, пустое (прозрачное). Итак, я предполагаю, что он падает, потому что на самом деле там ничего нет? Я попытался настроить разрешения в манифесте, чтобы разрешить доступ к SD-карте. Также отметим, что я тестирую на своем Galaxy sIII с включенным отладчиком. Я также снял защиту с SD-карты и отключил телефон, чтобы убедиться, что SD-карта была доступна, но каждый раз это один и тот же результат.
Еще раз спасибо. Вы все здесь довольно удивительны!
1 ответ
Итак, я выяснил свою проблему, и, надеюсь, это поможет другим людям, таким как я, с этой проблемой.
Короче говоря, если вы хотите получить высококачественную информацию из своего намерения CAMERA, вы должны (из того, что я нашел) сохранить изображение на SD-карту. Мое приложение возвращало пустое (то, что я думал, было прозрачным) изображение, потому что изображение никогда не существовало. Вы должны создать путь к файлу, это не автоматический процесс.
Я сделал это, просто установив статический путь, и создал temp.png в этом месте:
File photo = null;
File path = new File("storage/sdcard0/Android/data/com.ex.beerlog/");
String pathstring = path.toString();
if (!path.exists()) {
path.mkdirs();
Log.w(TAG, "*******Photo Directory Created*********");
} else { // do nothing
}
Наконец, я все еще хотел сохранить свои захваченные фотографии внутри, но размер изображения вызвал бы исключение Out of Memory (OOM). Поэтому, чтобы исправить это, я создал матрицу, которая уменьшала изображение до 350 пикселей в ширину (на самом деле изображение максимального размера, которое требуется моему приложению). ** Вы заметите "matrix.postrotate(90)", потому что мои фотографии в противном случае вернулись бы на свою сторону.
private Bitmap cropImage(Bitmap bmp2) {
// TODO Auto-generated method stub
int width = bmp2.getWidth();
int height = bmp2.getHeight();
float scale = (float) 350/bmp.getHeight();
Log.w(TAG, "*********Image Wt=" + width + ", Ht=" + height + " scale"+scale+"*********");
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
matrix.postRotate(90);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bmp2, 0, 0, width, height, matrix, true);
int bmpHtWidth = resizedBitmap.getWidth();
int bmpHeight = resizedBitmap.getHeight();
int bmpTop = (bmpHeight - bmpHtWidth) / 2;
Log.w(TAG, "*********resizedImage HtWt=" + bmpHtWidth + ", Ht=" + bmpHeight + ", top=" + bmpTop + "*********");
return resizedBitmap;
}
По сути, они ответили на мой вопрос выше. Надеюсь, это поможет кому-то еще!
РЕДАКТИРОВАТЬ:: О, наконец, я столкнулся с проблемой, когда я получил немного сумасшедший фото между действиями, в результате чего OOM. Чтобы исправить это, я использовал функцию Bitmap.recycle(), прежде чем моя деятельность закрылась и перешла к следующей активности. Это попытается освободить память между действиями.