2013年6月18日

【Android】ImageView顯示網路圖片(Converting Image URL to Bitmap)

各位Android安卓開發者大家好 >///<

今天小黑人要與大家分享的是"顯示網路圖片",也就是說藉由網路圖片的網址URL來進行讀取顯示的動作,這個應用在很多圖資的APP或龐大的APP應該是有很密切的關係,原因就是如果有太多的圖片資源放在本地端的話,會造成APP檔案過於龐大,所以最後在顯示圖片的部分大多都是會以顯示網路圖片為主,APP端只要知道圖片的連結網址就可以進行網路圖片擷取,這種簡單又方便的做法就讓小黑人跟大家分享吧。 ^^

1.首先,要進行讀取網路圖片的話必須先在AndroidManifest.xml加入網路連線權限
<uses-permission android:name="android.permission.INTERNET"/>
2.接下來只要在程式裡(.java)做讀取網路圖片的動作就完成了。
 public class MainActivity extends Activity
{
   private ImageView img;
   private Button btn;
       
   @Override
   protected void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
       
      //顯示網路圖片的ImageView與進行讀取網路圖片的Button
      img = (ImageView) findViewById(R.id.img);
      btn = (Button) findViewById(R.id.uri);

      btn.setOnClickListener(new OnClickListener()
      {
         @Override
         public void onClick(View arg0)
         {
            //建立一個AsyncTask執行緒進行圖片讀取動作,並帶入圖片連結網址路徑
            new AsyncTask<String, Void, Bitmap>()
            {
              @Override
              protected Bitmap doInBackground(String... params)
              {
                String url = params[0];
                return getBitmapFromURL(url);
              }
                       
              @Override
              protected void onPostExecute(Bitmap result)
              {
                img. setImageBitmap (result);
                super.onPostExecute(result);
              }      
            }.execute("圖片連結網址路徑");
         }
      });
   }
 
   //讀取網路圖片,型態為Bitmap
   private static Bitmap getBitmapFromURL(String imageUrl)
   {
      try
      {
         URL url = new URL(imageUrl);
         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
         connection.setDoInput(true);
         connection.connect();
         InputStream input = connection.getInputStream();
         Bitmap bitmap = BitmapFactory.decodeStream(input);
         return bitmap;
      }
      catch (IOException e)
      {
         e.printStackTrace();
         return null;
      }
   }
}
以上就是顯示網路圖片的實作程式碼,大家可以參考看看唷 ^^
再來就是向大家說明一下為什麼要在讀取圖片時外層還要用一層多執行緒包覆呢?原因就是在Android 4.0版本之後,為了防止在與網路串接溝通時造成程式整個停滯,卡住在網路溝通裡而無法繼續動作,所以現在的版本在與網路進行溝通時必須要建立一個多執行緒來進行網路讀取資料而不影響到程式其他的運作。
謝謝大家~如有任何問題都可以和小黑人一起交流討論喔~! XDD

23 則留言:

  1. 剛好需要這方面的資料,很感謝你!
    想請問我用這段程式碼擷取網頁上的圖片後,會不斷切換是正常的嗎?
    例如我預設圖片來源為A,而網頁上的圖片為B
    程式會一直在A,B之間切換...

    回覆刪除
    回覆
    1. 您好,很抱歉這麼久才回覆您!
      哈哈,小黑人這段時間忙著處理專題研究,真不好意思...
      根據您的提問小黑人向您解釋,
      答案當然是不正常!
      正常來說只要一讀取好網路圖片至手機端時本機預設圖就會被覆蓋住,
      不會有重覆切換的動作發生,
      小黑人猜想您發生重覆切換的原因可能是因為您有不斷呼叫網路讀取圖片的函式發生的,
      可能是在讀取網路圖時系統先切換至預設圖,然後再切換網路圖,但又持續呼叫網路讀圖,
      可能才這樣一直不斷切換,這是小黑人的猜測,再請您檢查看看。

      感謝您的提問!

      刪除
  2. 您好,很抱歉這麼久才回覆您!
    哈哈,小黑人這段時間忙著處理專題研究,真不好意思...
    根據您的提問小黑人向您解釋,
    答案當然是不正常!
    正常來說只要一讀取好網路圖片至手機端時本機預設圖就會被覆蓋住,
    不會有重覆切換的動作發生,
    小黑人猜想您發生重覆切換的原因可能是因為您有不斷呼叫網路讀取圖片的函式發生的,
    可能是在讀取網路圖時系統先切換至預設圖,然後再切換網路圖,但又持續呼叫網路讀圖,
    可能才這樣一直不斷切換,這是小黑人的猜測,再請您檢查看看。

    感謝您的提問!

    回覆刪除
  3. 您好
    我想請問您程式碼裡面的uri是怎麼來的呢?
    謝謝~

    回覆刪除
    回覆
    1. 您好,很抱歉這麼久才回覆您,
      根據您的提問,url是您可自行輸入的圖片網址,
      將網址帶入AsyncTask後即可進行讀取圖片的動作,
      感謝您的留言!

      刪除
  4. 請問一下
    如果我使用Google的協作平台
    在一個網址內放置(多數)圖片
    假設我的網址為 "http:********"
    網址內有 "xxx.jpg".............多張圖檔
    我該如何利用程式 將其 擷取下來 並依序排序呢?

    回覆刪除
    回覆
    1. 您好,根據您的提問小黑人與您解釋,
      如果有多張圖片的話,就可以使用迴圈方式進行下載,
      程式下載寫法也是一樣,只需要在外層新增一個迴圈下載即可,
      您可以先把圖片路徑放入陣列裡,例如: String[] Pics = {"http://...xxx1.jpg",""http://...xxx2.jpg""......};

      感謝您的提問!

      刪除
    2. 小黑,關於你說用陣列存網址位置,我還是有點不明白,能不能具體的舉例給我呢?感謝你。

      刪除
  5. 超感謝你~~我的bitmap一直讀不到string url的值,都顯示空值
    終於解決我的問題了!

    回覆刪除
    回覆
    1. 您好,非常感謝您的支持!
      有任何問題都可以一起交流討論 ^^

      刪除
  6. 請問你的這隻程式
    有用在三星的手機過嗎~~android版本4.1.2
    因為我自己寫了一套程式
    關於讀取圖檔方面採用你的方式
    但是
    讀取玩都會自動黑掉
    但Htc newone 版本4.4.2 卻可以執行正常
    請問這個有差嗎~~

    回覆刪除
    回覆
    1. 您好,很抱歉這麼久才回覆您,
      根據您的提問小黑人與您解釋,
      範例程式碼是都可以通用的喔,
      小黑人也有用三星的手機進行測試,結果也是可以正常顯示,
      可能要麻煩您看一下顯示的錯誤訊息是什麼,這樣才可以知道問題是什麼.

      感謝您的提問!

      刪除
  7. 想請問能否利用 上面所說的不斷呼叫網路讀取圖片 來做出像是 windows Phone 一樣的動態磚呢

    可以請你示範 動態磚嗎 謝謝 >///<

    回覆刪除
    回覆
    1. 好的,沒有問題。

      感謝您的建議與留言!

      刪除
  8. 請問一下有辦法讓使用者上傳圖片到mysql資料庫裡,再用android顯示出儲存在資料庫裡的圖片嗎

    回覆刪除
    回覆
    1. 您好,根據您的提問小黑人與您解釋,
      答案是可以,但是不建議這樣做,
      如果讓使用者可以直接把圖片寫入到資料庫裡的話,
      就有可能會發生同一時間很多使用者都在對資料庫寫入的狀況,
      比較建議在手機裝置與資料庫之間可以藉由後台api來做相互的溝通。

      感謝您的提問!

      刪除
  9. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 您好,很抱歉這麼久才回覆您,
      根據您的提問小黑人與您解釋,
      如果要一開啟App就進行讀取動作的話,
      您可以把原本Button Click內的動作放至onStart()的方法裡,這樣在開啟App時就會直接讀取圖片,範例如下:

      @Override
      protected void onStart()
      {
      super.onStart();

      new AsyncTask()
      {
      @Override
      protected Bitmap doInBackground(String... params)
      {
      String url = params[0];
      return getBitmapFromURL(url);
      }

      @Override
      protected void onPostExecute(Bitmap result)
      {
      img. setImageBitmap (result);
      super.onPostExecute(result);
      }
      }.execute("圖片連結網址路徑");
      }

      感謝您的提問!

      刪除
  10. 請問一下你的程式是必須先點一下Button然後顯示Image嗎?
    因為我試了一下你的程式在我開啟app時他並不會自動顯示圖片,我必須要先點下Button然後圖片才會顯示.
    我想要讓ImageButton在app打開時直接自動讀取網路圖片,然後點下ImageButton的時候就能進入網頁,請問這有什麼方法可以做到嗎?

    回覆刪除
    回覆
    1. 您好,很抱歉這麼久才回覆您,
      根據您的提問小黑人與您解釋,
      如果要一開啟App就進行讀取動作的話,
      您可以把原本Button Click內的動作放至onStart()的方法裡,這樣就會直接讀取圖片,範例如下:
      @Override
      protected void onStart()
      {
      super.onStart();

      new AsyncTask()
      {
      @Override
      protected Bitmap doInBackground(String... params)
      {
      String url = params[0];
      return getBitmapFromURL(url);
      }

      @Override
      protected void onPostExecute(Bitmap result)
      {
      img. setImageBitmap (result);
      super.onPostExecute(result);
      }
      }.execute("圖片連結網址路徑");
      }

      至於按下Button後就可以更改成顯示網頁的動作。

      感謝您的提問!

      刪除
  11. btn = (Button) findViewById(R.id.uri);
    這裡要改成 btn = (Button) findViewById(R.id.btn);

    只是小筆誤,感謝作者,已成功^^

    回覆刪除
  12. 推一個,好厲害,怎麼知道或找到要用 Asynchronous?

    回覆刪除
  13. 該怎麼顯示SERVER的所有圖片 不用輸入檔案名稱

    回覆刪除

謝謝大家支持,有任何問題都可以和小黑人一起討論!