Android Dev:从存储在 SD 卡上的临时文件创建位图,设置 ImageView,然后将其存储在本地
Posted
技术标签:
【中文标题】Android Dev:从存储在 SD 卡上的临时文件创建位图,设置 ImageView,然后将其存储在本地【英文标题】:Android Dev: Creating a Bitmap from a temp file stored on the SD card, setting an ImageView, then storing it locally 【发布时间】:2013-03-07 15:14:28 【问题描述】:因此,由于仅从 android.media.action.IMAGE_CAPTURE 获取数据的质量问题,我显然需要调用活动,保存一个本地临时文件,然后我可以从中创建位图。这个Bitmap会被裁剪成一个正方形,设置成一个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 ResultInfowho=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 卡可用,但每次结果都是一样的。
再次感谢。你们在这方面都很棒!
【问题讨论】:
您是在设备还是模拟器上进行测试?编辑:我看到有人提到手机没关系。 就像我在帖子末尾提到的那样,有一个设备(我想我没有明确说设备)。银河sIII。我知道 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
最后我仍然想在内部存储我拍摄的照片,但图像大小会导致内存不足 (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;
这些基本上回答了我上面的问题。希望它也对其他人有所帮助!
编辑:哦,最后我遇到了一个问题,因为我在活动之间疯狂地拍了一张照片,导致 OutOfMemoryException。为了解决这个问题,我在活动关闭并移至下一个活动之前使用了 Bitmap.recycle() 函数。这将尝试在活动之间释放一些内存。
【讨论】:
以上是关于Android Dev:从存储在 SD 卡上的临时文件创建位图,设置 ImageView,然后将其存储在本地的主要内容,如果未能解决你的问题,请参考以下文章