Android - 如何放置从sdcard或相机胶卷加载图像的imageview?

时间:2012-11-05 18:44:15

标签: android android-intent android-camera android-imageview android-sdcard

我正在编写一个应用程序,我需要通过点击它来放置用户必须加载图像的图像视图。点击后,我将为用户提供选项,让他们选择是否打算从手机本身加载存储的图像,或从相机拍摄新镜头。

这个问题可能是多余的,但几乎没有一个类似的问题/问题在这里没有达到我想要做的。

P.S。我正在使用安装了Eclipse 4.2(JUNO)SDK的Android API15。

以下是主要活动的代码段代码,它给出了一个错误:

 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 ResultInfo{who=null, request=1337, result=-1, data=Intent { act=inline-data (has extras) }} to activity {test.imgbyte.conerter/test.imgbyte.conerter.FindImgPathActivity}: java.lang.NullPointerException

1 个答案:

答案 0 :(得分:4)

阿。这个错误。我花了很多时间来破译它的意思,显然结果有一些你想要访问的空字段。在你的情况下,你没有真正用文件初始化的mImageCaptureUri字段。启动相机意图的方法是创建一个文件,并将它的Uri作为EXTRA_OUTPUT传递给intent。

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

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

鉴于我们正处于这一点,让我与大家分享一下我上周学到的关于直接加载Bitmaps的非常重要的一点......不要这样做!我花了一个星期的时间来理解为什么,当我这么做的时候,我简直不敢相信我之前没有理解,这一切都是在记忆中发挥作用。

使用此代码有效加载位图。 (一旦你有了这个文件,只需在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);  
          }
    }    
}