Android 如何使用Uri和位图工厂将图像加载到imageView中

Android 如何使用Uri和位图工厂将图像加载到imageView中,android,imageview,Android,Imageview,我将Uri传递给一个新活动,并尝试使用它在新活动中创建imageView。我使用InputStream和BitmapFactory来实现这一点。我的照片一直显示为黑色,但我不知道为什么 第一页: public void galleryClicked(View view){ Intent intent = new Intent(Intent.ACTION_PICK); File pictureDirectory = Environment.getExternalStorageP

我将Uri传递给一个新活动,并尝试使用它在新活动中创建imageView。我使用InputStream和BitmapFactory来实现这一点。我的照片一直显示为黑色,但我不知道为什么

第一页:

public void galleryClicked(View view){

    Intent intent = new Intent(Intent.ACTION_PICK);

    File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    String pictureDirectoryPath = pictureDirectory.getPath();

    Uri data = Uri.parse(pictureDirectoryPath);

    intent.setDataAndType(data, "image/*");

    startActivityForResult(intent, GALLERY_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(resultCode == RESULT_OK ){
        Intent intent = new Intent(this, Tattoo_Page.class);
        intent.putExtra("picture", data.getData());
        startActivity(intent);
    }
}
纹身页面:

public class Tattoo_Page extends Activity {

private ImageView picture;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.tattoo_page);

    Bundle extras = getIntent().getExtras();
    picture = (ImageView) findViewById(R.id.picture);

    Uri imageUri = (Uri) extras.get("picture");


    try {

        InputStream inputStream = getContentResolver().openInputStream(imageUri);

        Bitmap image = BitmapFactory.decodeStream(inputStream);

        picture.setImageBitmap(image);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        Toast.makeText(this, "Unable to open image", Toast.LENGTH_LONG).show();
    }

}
}

XML:


舱单:

<?xml version="1.0" encoding="utf-8"?>



您正在访问主线程中的图像。这是非常不合适的,因为它可能会减慢你的应用程序,并可能会在内存加载完成之前降低帧速率

有一个很棒的库,它将整个过程抽象到一个子线程中,并将其应用到布局中

进入。通过将
compile'com.squareup.picasso:picasso:2.5.2'
添加到项目依赖项中,您可以将其包含到项目中,然后您只需编写以下简单的代码即可从web下载图像:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
在处理磁盘映像时,您可能希望改用此加载程序:

Picasso.with(context).load(new File(...)).into(imageView);
就这样。你完了

另外,Android上的图像加载的许多常见陷阱都是由毕加索自动处理的:

  • 在适配器中处理
    ImageView
    回收和下载取消
  • 使用最少内存的复杂图像转换
  • 自动内存和磁盘缓存
此外,它速度更快,重量更轻。整个jar文件只有118KB,比几乎任何实现都快(如果不是更快的话)

TL;医生:


使用。所有酷孩子都在做这件事。

您可以使用下面的代码执行确切的任务:

public void galleryClicked(View v){
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(Intent.createChooser(intent, "Complete action using"), 0);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 0 && resultCode == getActivity().RESULT_OK) {
        Uri selectedImageUri = data.getData();
        String[] fileColumns = {MediaStore.Images.Media.DATA};
        Cursor cursor = getActivity().getContentResolver().query(selectedImageUri, fileColumns, null, null, null);
        cursor.moveToFirst();
        int cIndex = cursor.getColumnIndex(fileColumns[0]);
        String picturePath = cursor.getString(cIndex);
        cursor.close();
        if (picturePath != null) {
            Intent intent = new Intent(this, Tattoo_Page.class);
            intent.putExtra("picture", picturePath);
            startActivity(intent);
        }
    }
}
Tatoo_页面活动

public class Tattoo_Page extends Activity {

public static int IMAGE_MAX_WIDTH=1024;
public static int IMAGE_MAX_HEIGHT=768;
private ImageView picture;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.tattoo_page);

Bundle extras = getIntent().getExtras();
picture = (ImageView) findViewById(R.id.picture);

String imagePath =  extras.getStringExtra("picture");


new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                final Bitmap bitmap = decodeFile(new File(picturePath));
                if (bitmap != null) {
                    Tatoo_Page.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            picture.setImageBitmap(bitmap);
                        }
                    });
                }else{
                        Toast.makeText(Tatoo_page.this,"Error",Toast.LENGTH_SHORT).show();
                }
            }catch(Exception e){
                e.printStackTrace();
                Toast.makeText(ProfileFragment.this.getActivity(),"Problem loading file",Toast.LENGTH_SHORT).show();
            }
        }
    }).start();

}
//This function will decode the file stream from path with appropriate size you need. 
//Specify the max size in the class 
private Bitmap decodeFile(File f) throws Exception{
    Bitmap b = null;

    //Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;

    FileInputStream fis = new FileInputStream(f);
    BitmapFactory.decodeStream(fis, null, o);
    fis.close();

    int scale = 1;
    int IMAGE_MAX_SIZE=Math.max(IMAGE_MAX_HEIGHT,IMAGE_MAX_WIDTH);
    if (o.outHeight > IMAGE_MAX_HEIGHT || o.outWidth > IMAGE_MAX_WIDTH) {
        scale = (int)Math.pow(2, (int) Math.ceil(Math.log(IMAGE_MAX_SIZE /
                (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
    }

    //Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    fis = new FileInputStream(f);
    b = BitmapFactory.decodeStream(fis, null, o2);
    fis.close();

    return b;
}

有趣。不过,我不是从URL加载的。这对本地图像仍然有效吗?你有设置权限吗?哇!这是编写所有代码的快速周转时间。我现在来测试一下。谢谢。如果在棉花糖及以上设备上进行测试,请确保编写运行时权限代码。
public void galleryClicked(View v){
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(Intent.createChooser(intent, "Complete action using"), 0);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 0 && resultCode == getActivity().RESULT_OK) {
        Uri selectedImageUri = data.getData();
        String[] fileColumns = {MediaStore.Images.Media.DATA};
        Cursor cursor = getActivity().getContentResolver().query(selectedImageUri, fileColumns, null, null, null);
        cursor.moveToFirst();
        int cIndex = cursor.getColumnIndex(fileColumns[0]);
        String picturePath = cursor.getString(cIndex);
        cursor.close();
        if (picturePath != null) {
            Intent intent = new Intent(this, Tattoo_Page.class);
            intent.putExtra("picture", picturePath);
            startActivity(intent);
        }
    }
}
public class Tattoo_Page extends Activity {

public static int IMAGE_MAX_WIDTH=1024;
public static int IMAGE_MAX_HEIGHT=768;
private ImageView picture;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.tattoo_page);

Bundle extras = getIntent().getExtras();
picture = (ImageView) findViewById(R.id.picture);

String imagePath =  extras.getStringExtra("picture");


new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                final Bitmap bitmap = decodeFile(new File(picturePath));
                if (bitmap != null) {
                    Tatoo_Page.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            picture.setImageBitmap(bitmap);
                        }
                    });
                }else{
                        Toast.makeText(Tatoo_page.this,"Error",Toast.LENGTH_SHORT).show();
                }
            }catch(Exception e){
                e.printStackTrace();
                Toast.makeText(ProfileFragment.this.getActivity(),"Problem loading file",Toast.LENGTH_SHORT).show();
            }
        }
    }).start();

}
//This function will decode the file stream from path with appropriate size you need. 
//Specify the max size in the class 
private Bitmap decodeFile(File f) throws Exception{
    Bitmap b = null;

    //Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;

    FileInputStream fis = new FileInputStream(f);
    BitmapFactory.decodeStream(fis, null, o);
    fis.close();

    int scale = 1;
    int IMAGE_MAX_SIZE=Math.max(IMAGE_MAX_HEIGHT,IMAGE_MAX_WIDTH);
    if (o.outHeight > IMAGE_MAX_HEIGHT || o.outWidth > IMAGE_MAX_WIDTH) {
        scale = (int)Math.pow(2, (int) Math.ceil(Math.log(IMAGE_MAX_SIZE /
                (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
    }

    //Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    fis = new FileInputStream(f);
    b = BitmapFactory.decodeStream(fis, null, o2);
    fis.close();

    return b;
}