Android - 如何放置一个从 SD 卡或相机胶卷加载图像的图像视图?

Posted

技术标签:

【中文标题】Android - 如何放置一个从 SD 卡或相机胶卷加载图像的图像视图?【英文标题】:Android - How to put an imageview that loads image from sdcard or camera roll? 【发布时间】:2012-10-25 15:44:30 【问题描述】:

我正在编写一个应用程序,我需要放置一个图像视图,用户必须通过单击它来加载图像。单击“我要”后,用户可以选择他是打算从手机本身加载存储的图像还是从它的相机拍摄新照片。

这个问题可能是多余的,但这里揭示的类似问题/问题几乎都没有达到我想要做的事情。

附:我正在使用安装了 Eclipse 4.2 (JUNO) SDK 的 android API15。

这是主要活动的 sn-p 代码,它给了我一个错误:

 package test.imgbyte.conerter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import android.net.Uri;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.view.View;

public class FindImgPathActivity extends Activity 


      private Uri mImageCaptureUri;
      static final int CAMERA_PIC_REQUEST = 1337; 

      public void onCreate(Bundle savedInstanceState)
      
        super.onCreate(savedInstanceState);
        setContentView(R.layout.imgfilepath);

        Button camera = (Button) findViewById(R.id.btnLoad);
        camera.setOnClickListener(new View.OnClickListener() 
        
            public void onClick(View v) 
            
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
                startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);               
                           
        );

      
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_PIC_REQUEST) 
          
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            ImageView image = (ImageView) findViewById(R.id.imgLoaded);  
            image.setImageBitmap(thumbnail);  

            String pathToImage = mImageCaptureUri.getPath();

            // pathToImage is a path you need. 

            // If image file is not in there, 
            //  you can save it yourself manually with this code:
            File file = new File(pathToImage);

            FileOutputStream fOut;
            try 
            
                fOut = new FileOutputStream(file);
                thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, fOut); // You can choose any format you want
             
            catch (FileNotFoundException e) 
            
                e.printStackTrace();
            

          
        

我从 LogCat 得到的错误是这样的:

11-05 19:23:11.777: E/AndroidRuntime(1206): FATAL EXCEPTION: main
11-05 19:23:11.777: E/AndroidRuntime(1206): java.lang.RuntimeException: Failure delivering result ResultInfowho=null, request=1337, result=-1, data=Intent  act=inline-data (has extras)  to activity test.imgbyte.conerter/test.imgbyte.conerter.FindImgPathActivity: java.lang.NullPointerException

【问题讨论】:

我想你可以在这里参考答案:[***.com/questions/2507898/… [1]:***.com/questions/2507898/… 【参考方案1】:

啊。这个错误。我花了很长时间来解读它的含义,显然结果有一些你试图访问的空字段。在您的情况下,您尚未使用文件真正初始化的是 mImageCaptureUri 字段。启动相机 Intent 的方法是创建一个文件,并将其 Uri 作为 EXTRA_OUTPUT 传递给 Intent。

File tempFile = new File("blah.jpg");
...
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
...

然后您可以使用 file.getAbsolutePath() 方法来加载位图。

鉴于我们在这一点上,让我与您分享我上周学到的关于直接加载位图的非常重要的一点......不要这样做!我花了一周的时间才明白为什么,当我明白的时候,我简直不敢相信我之前没有明白,这完全是记忆游戏。

使用此代码有效地加载位图。 (获得文件后,只需在 BitmapFactory.decodeFile() 中使用 file.getAbsolutePath()):

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) 
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) 
            if (width > height) 
                inSampleSize = Math.round((float)height / (float)reqHeight);
             else 
                inSampleSize = Math.round((float)width / (float)reqWidth);
            
        
        return inSampleSize;
    

    public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) 

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    

只需将您的 file.getAbsolutePath() 作为第一个参数以及所需的宽度和高度传递给 decodeSampledBitmapFromPath 函数,即可获得有效加载的位图。此代码是根据 Android 文档上的 version here 修改而来的。

编辑:

private Uri mImageCaptureUri; // This needs to be initialized.
      static final int CAMERA_PIC_REQUEST = 1337; 
private String filePath;

      public void onCreate(Bundle savedInstanceState)
      
        super.onCreate(savedInstanceState);
        setContentView(R.layout.imgfilepath);
// Just a temporary solution, you're supposed to load whichever directory you need here
        File mediaFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Temp1.jpg");
filePath = mediaFile.getABsolutePath();

        Button camera = (Button) findViewById(R.id.btnLoad);
        camera.setOnClickListener(new View.OnClickListener() 
        
            public void onClick(View v) 
            
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
                startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);               
                           
        );

      
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_PIC_REQUEST) 
          
            if(resultCode == RESULT_OK)
          
int THUMBNAIL_SIZE = 64;
// Rest assured, if the result is OK, you're file is at that location
            Bitmap thumbnail = decodeSampledBitmapFromPath(filePath, THUMBNAIL_SIZE, THUMBNAIL_SIZE); // This assumes you've included the method I mentioned above for optimization
            ImageView image = (ImageView) findViewById(R.id.imgLoaded);  
            image.setImageBitmap(thumbnail);  
          
        

【讨论】:

你能推荐一个编辑过的我的代码的 sn-p 插入你的建议吗?我会非常感激,因为 atm 作为 Android 平台上的初学者让我习惯于解决我在途中遇到的问题的解决方案。 我已经添加了内联代码。为了更好地理解所有这些,请阅读文档,当我遇到这个问题时,正是我在文档上花费的 3 天时间才让我摆脱了困境,并教会了我很多东西。干杯。

以上是关于Android - 如何放置一个从 SD 卡或相机胶卷加载图像的图像视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何将图像从安卓相机上传到网络服务器(不在应用程序中)

将图像存储在 android 中的 SD 卡或 SQL lite DB 中的最佳做法是啥?

触发图像点击事件时,如何将图像保存到手机内存(例如 SD 卡或本地硬盘驱动器)?

Android:保存用户使用相机拍摄的照片

如何识别从UITabBarController中的更多选项卡或单独选项卡单击视图控制器?

如何在android中结合覆盖位图和捕获的图像?