2016-09-29 63 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

相關問題