2016-09-29 21 views
1

我正在将Uri传递给一个新活动并尝试使用它在新活动中创建imageView。我使用InputStream和BitmapFactory来实现这一点。尽管如此,我的照片一直显示为黑色,我不知道为什么。如何使用Uri和位图工厂将图像加载到imageView中

First_Page:

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); 
    } 
} 

Tattoo_Page:

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:

<ImageView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/picture" 
    android:scaleType="fitCenter"/> 

清单:

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

<uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.hardware.camera.autofocus" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.INTERNET"/> 
<uses-feature android:name="android.hardware.camera2" /> 
<uses-feature android:name="android.hardware.camera.any" /> 


<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/Theme.AppCompat.NoActionBar" 
    android:screenOrientation="portrait"> 
    <activity android:name=".First_Page"> 

     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <activity android:name=".Tattoo_Page"> </activity> 

</application> 

+0

你已经设置该权限? – emiliopedrollo

回答

1

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

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_Page活动

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; 
} 
+0

哇!这是编写所有代码的快速周转时间。我现在会测试它。谢谢。 – Mardymar

+0

如果在棉花糖和以上设备上进行测试,请确保您编写运行时权限的代码。 –

1

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

有一个很棒的库,它将子进程中的整个进程抽象出来并应用到布局中。

输入Picasso。你包括它到你的项目中加入compile 'com.squareup.picasso:picasso:2.5.2'到您的项目依赖关系,然后你只写这个简单的线路从网站上下载图片:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); 

当你正在处理的磁盘映像可能要使用这部分代码来代替:

Picasso.with(context).load(new File(...)).into(imageView); 

就是这样。你完成了。

作为奖励,图像加载Android上许多常见的陷阱是由毕加索自动处理::

  • 处理ImageView回收和下载取消在适配器。
  • 复杂的图像转换与最小的内存使用。
  • 自动内存和磁盘缓存。

此外,它是令人难以置信的更快,更轻量。比几乎任何实现都快得多(如果不是更快),ENTIRE jar文件只有118 kb。

TL; DR:

使用Picasso。所有时尚的年轻人都这样做。

+0

有趣。不过,我不是从URL加载的。这仍然适用于本机图像? – Mardymar

+0

当然。它适用于网络,磁盘和内存。 – emiliopedrollo

相关问题