Android开发人员:从存储在SD卡上的临时文件创建位图,设置ImageView,然后将其存储在本地

Android开发人员:从存储在SD卡上的临时文件创建位图,设置ImageView,然后将其存储在本地,android,bitmap,android-sdcard,fileinputstream,Android,Bitmap,Android Sdcard,Fileinputstream,因此,由于从android.media.action.IMAGE_捕获中获取数据的质量问题,我显然需要调用活动,保存一个本地临时文件,然后从中创建位图。该位图将被裁剪成正方形,设置为ImageView,然后本地存储;然而,我有一些问题。一切(现在不包括裁剪)都可以设置图像(它返回一个空白图像)并在内部存储,此时图像崩溃。我试图用文件管理器在SD卡上查找文件,但文件夹甚至没有显示,因此我不知道文件是否真的被创建。知道我做错了什么吗?守则: private static final String T

因此,由于从android.media.action.IMAGE_捕获中获取数据的质量问题,我显然需要调用活动,保存一个本地临时文件,然后从中创建位图。该位图将被裁剪成正方形,设置为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卡可用,但每次的结果都是一样的


再次感谢。你们都对这玩意很在行

好吧,我解决了我的问题,希望这能帮助像我这样的人解决这个问题

长短不一的是,如果你想从你的相机中收集高质量的信息,你必须(根据我的发现)将图像保存到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)异常。所以为了解决这个问题,我创建了一个矩阵,将图像缩小到350px宽(实际上是我的应用程序需要的最大尺寸的图像)**你会注意到一个“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()在我的活动关闭并移动到下一个活动之前执行此函数。这将尝试在活动之间释放一些内存。

您是在设备或模拟器上测试此函数吗?编辑:我看到一个关于手机nevermind的提述。正如我在文章末尾提到的,那里有一个设备(我想我没有明确提到设备).A Galaxy sIII。我知道SD卡在插入计算机时不可用,但即使在拔下电缆进行测试后,我也会得到相同的效果。