Làm cách nào để tải ImageView bằng URL trong Android? [đóng cửa]


530

Làm thế nào để bạn sử dụng một hình ảnh được tham chiếu bởi URL trong một ImageView?



Câu trả lời:


713

Từ nhà phát triển Android :

// show The Image in a ImageView
new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
            .execute("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png");

public void onClick(View v) {
    startActivity(new Intent(this, IndexActivity.class));
    finish();

}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}

Hãy chắc chắn rằng bạn có các quyền sau đây được thiết lập AndroidManifest.xmlđể truy cập internet.

<uses-permission android:name="android.permission.INTERNET" />

39
Điều này thật tuyệt. Và nên cao hơn nhiều trong danh sách. Các asynctask cho phép tải cái này mà không đóng băng UI!
Kyle Clegg

3
AsyncT task sử dụng một bộ thực thi nối tiếp, nghĩa là mỗi hình ảnh sẽ tải từng cái một và không thực hiện tải luồng song song.
Blundell

2
Liên kết nguồn không hoạt động nữa ...
hecvd

10
Luồng đầu vào không được đóng trong ví dụ của bạn. Tốt nhất được thực hiện trong khối cuối cùng của thử / bắt của bạn.
Risadinha

2
Phương pháp này có còn phù hợp không? Tôi hơi bối rối về phương thức OnClick () và mục đích của nó
tccpg288

170

1. Picasso cho phép tải hình ảnh không rắc rối trong ứng dụng của bạn thường xuyên trong một dòng mã!

Sử dụng lớp:

implementation 'com.squareup.picasso:picasso:2.71828'

Chỉ cần một dòng mã!

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

2. Glide Một thư viện tải và lưu trữ hình ảnh cho Android tập trung vào việc cuộn mượt mà

Sử dụng lớp:

repositories {
  mavenCentral() 
  google()
}

dependencies {
   implementation 'com.github.bumptech.glide:glide:4.7.1'
   annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}

// Để xem đơn giản:

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

3. fresco là một hệ thống mạnh mẽ để hiển thị hình ảnh trong các ứng dụng Android.Fresco đảm nhiệm việc tải và hiển thị hình ảnh, vì vậy bạn không cần phải làm vậy.

Bắt đầu với Fresco


2
Vì vậy, nếu url là localhost, có nghĩa là hình ảnh nằm trong cơ sở dữ liệu máy chủ cục bộ của hệ thống đang phát triển như xampp, vẫn có thể lấy hình ảnh từ url =.
blackjack

2
@blackjack - localhost từ ứng dụng sẽ là điện thoại thông minh. Để truy cập hệ thống đang phát triển của bạn, điện thoại thông minh và hệ thống đang phát triển của bạn sẽ phải ở cùng một mạng và bạn phải sử dụng địa chỉ IP của hệ thống đang phát triển của mình trong mạng đó.
Rực rỡ

1
Có thể sử dụng picasso để tải hình ảnh trên nút?
mahdi

1
@chiragkyada tôi thử với mã này Picasso.with (bối cảnh) .load (url) .into (button_view); nhưng nó hiển thị lỗi cho: vào (button_view)
mahdi

1
Tôi nghĩ rằng đây nên là câu trả lời được chấp nhận
Udo

150

Bạn sẽ phải tải hình ảnh trước tiên

public static Bitmap loadBitmap(String url) {
    Bitmap bitmap = null;
    InputStream in = null;
    BufferedOutputStream out = null;

    try {
        in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);

        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
        copy(in, out);
        out.flush();

        final byte[] data = dataStream.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();
        //options.inSampleSize = 1;

        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
    } catch (IOException e) {
        Log.e(TAG, "Could not load Bitmap from: " + url);
    } finally {
        closeStream(in);
        closeStream(out);
    }

    return bitmap;
}

Sau đó, sử dụng Imageview.setImageBitmap để đặt bitmap vào ImageView


126
bạn đúng nhưng chỉ cần 3 dòng này giúp giải quyết vấn đề. URL newurl = URL mới (photo_url_str); mIcon_val = BitmapFactory.decodeStream (newurl.openConnection () .getInputStream ()); profile_photo.setImageBitmap (mIcon_val); cảm ơn bạn đã trả lời
Praveen

2
Đối với URL - nhập java.net.URL; riêng tư tĩnh cuối cùng IO_BUFFER_SIZE = 4 * 1024; cái cuối cùng là gì?
Steve


@SACPK bạn nên viết nhận xét của mình dưới dạng câu trả lời để có thể nhận được bình chọn
Jim Wallace

câu trả lời phù hợp với tôi ,, đăng nó dưới dạng câu trả lời :)
omnia Mm

71

Tôi đã viết một lớp để xử lý việc này, vì nó dường như là một nhu cầu định kỳ trong các dự án khác nhau của tôi:

https://github.com/koush/UrlImageViewHelper

UrlImageViewHelper sẽ lấp đầy ImageView bằng một hình ảnh được tìm thấy tại một URL.

Mẫu sẽ thực hiện Tìm kiếm hình ảnh của Google và tải / hiển thị kết quả không đồng bộ.

UrlImageViewHelper sẽ tự động tải xuống, lưu và lưu trữ tất cả các hình ảnh url của BitmapDrawables. Các url trùng lặp sẽ không được tải vào bộ nhớ hai lần. Bộ nhớ bitmap được quản lý bằng cách sử dụng bảng băm tham chiếu yếu, vì vậy ngay khi hình ảnh không còn được bạn sử dụng nữa, nó sẽ được thu gom rác tự động.


Nhân tiện, giấy phép này là gì?
Ehtesh Choudhury

@Shurane - Apache. Tôi sẽ ghi chú lại sau.
koush

1
Có vẻ như chúng ta cần sử dụng cái này thay vì github.com/koush/ion vì UrlImageViewHelper đã không được chấp nhận như hiển thị trên trang của dự án github tại github.com/koush/UrlImageViewHelper .
Svetoslav Marinov

69

Dù sao mọi người hỏi bình luận của tôi để gửi nó như là câu trả lời. tôi đang đăng

URL newurl = new URL(photo_url_str); 
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection().getInputStream());
profile_photo.setImageBitmap(mIcon_val);

Điều này ngắn và tuyệt vời, cảm ơn
Nactus

18
mm .. điều này không thể được thực hiện từ luồng UI.
Guy

2
Đối với những người gặp vấn đề với "Loại bỏ URL không đúng định dạng", hãy bao quanh các dòng trên trong một lần thử / bắt. stackoverflow.com/a/24418607/2093088
Riot đi giả mạo

1
Điều này nên được thực hiện bằng AsyncTask như được mô tả ở trên
B-GangsteR

63

Câu trả lời được chấp nhận ở trên là tuyệt vời nếu bạn đang tải hình ảnh dựa trên một lần bấm nút, tuy nhiên nếu bạn đang thực hiện nó trong một hoạt động mới, nó sẽ đóng băng UI trong một hoặc hai giây. Nhìn xung quanh tôi thấy rằng một asynctask đơn giản đã loại bỏ vấn đề này.

Để sử dụng một asynctask, hãy thêm lớp này vào cuối hoạt động của bạn:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }    
}

Và gọi từ phương thức onCreate () của bạn bằng cách sử dụng:

new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
        .execute(MY_URL_STRING);

Kết quả là một hoạt động được tải nhanh và một lượt xem hình ảnh hiển thị một phần giây sau đó tùy thuộc vào tốc độ mạng của người dùng.


Điều này thật nhanh chóng và gọn nhẹ. Đáp ứng nhu cầu của tôi độc đáo! Cảm ơn!
Đánh dấu Murphy

như dấu ấn thời gian của tôi, điều này làm việc cho tôi!
Carpk

25

Bạn cũng có thể sử dụng chế độ xem LoadingImageView này để tải hình ảnh từ một url:

http://blog.blundellapps.com/imageview-with-loading-spinner/

Khi bạn đã thêm tệp lớp từ liên kết đó, bạn có thể khởi tạo chế độ xem hình ảnh url:

trong xml:

<com.blundell.tut.LoaderImageView
  android:id="@+id/loaderImageView"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  image="http://developer.android.com/images/dialog_buttons.png"
 />

Trong mã:

final LoaderImageView image = new LoaderImageView(this, "http://developer.android.com/images/dialog_buttons.png");

Và cập nhật nó bằng cách sử dụng:

image.setImageDrawable("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png");

Mẫu đẹp, nhưng tôi không tin đây là chủ đề an toàn. Tôi đang cố gắng sử dụng nó trong Async onPostExecute, tuy nhiên đôi khi onPostExecute có thể kết thúc trước khi nhận được cuộc gọi lại hiển thị hình ảnh null.
Jimmy

Điều này quản lý chủ đề riêng của nó. Vậy tại sao bạn không gọi ASyncTask trở lại UI khi nó kết thúc, với url bạn muốn. Bằng cách đó, bạn không có chủ đề sinh sản chủ đề.
Blundell

10
public class LoadWebImg extends Activity {

String image_URL=
 "http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png";

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       ImageView bmImage = (ImageView)findViewById(R.id.image);
    BitmapFactory.Options bmOptions;
    bmOptions = new BitmapFactory.Options();
    bmOptions.inSampleSize = 1;
    Bitmap bm = LoadImage(image_URL, bmOptions);
    bmImage.setImageBitmap(bm);
   }

   private Bitmap LoadImage(String URL, BitmapFactory.Options options)
   {       
    Bitmap bitmap = null;
    InputStream in = null;       
       try {
           in = OpenHttpConnection(URL);
           bitmap = BitmapFactory.decodeStream(in, null, options);
           in.close();
       } catch (IOException e1) {
       }
       return bitmap;               
   }

private InputStream OpenHttpConnection(String strURL) throws IOException{
 InputStream inputStream = null;
 URL url = new URL(strURL);
 URLConnection conn = url.openConnection();

 try{
  HttpURLConnection httpConn = (HttpURLConnection)conn;
  httpConn.setRequestMethod("GET");
  httpConn.connect();

  if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
   inputStream = httpConn.getInputStream();
  }
 }
 catch (Exception ex)
 {
 }
 return inputStream;
}
}

Cảm ơn rất nhiều, ví dụ hoàn hảo mà tôi đang tìm kiếm ................, nhưng theo Chủ đề sai, điều này đáng lẽ phải có ở đây ==> Cách đặt hình ảnh của viewView từ một chuỗi ?
VenomVendor

10

Xin chào Tôi có mã dễ nhất thử cái này

    public class ImageFromUrlExample extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);  
            ImageView imgView =(ImageView)findViewById(R.id.ImageView01);
            Drawable drawable = LoadImageFromWebOperations("http://www.androidpeople.com/wp-content/uploads/2010/03/android.png");
            imgView.setImageDrawable(drawable);

    }

    private Drawable LoadImageFromWebOperations(String url)
    {
          try{
        InputStream is = (InputStream) new URL(url).getContent();
        Drawable d = Drawable.createFromStream(is, "src name");
        return d;
      }catch (Exception e) {
        System.out.println("Exc="+e);
        return null;
      }
    }
   }

tệp chính

  <LinearLayout 
    android:id="@+id/LinearLayout01"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
   <ImageView 
       android:id="@+id/ImageView01"
       android:layout_height="wrap_content" 
       android:layout_width="wrap_content"/>

thử cái này


10

Theo tôi, thư viện hiện đại tốt nhất cho một nhiệm vụ như vậy là Picasso by Square. Nó cho phép tải một hình ảnh vào ImageView bằng URL với một lớp lót:

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

9

Gần đây tôi đã tìm thấy một chủ đề ở đây , vì tôi phải làm một điều tương tự cho một listview với hình ảnh, nhưng nguyên tắc rất đơn giản, như bạn có thể đọc trong lớp mẫu đầu tiên được hiển thị ở đó (bởi jleedev). Bạn nhận được luồng đầu vào của hình ảnh (từ web)

private InputStream fetch(String urlString) throws MalformedURLException, IOException {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpGet request = new HttpGet(urlString);
    HttpResponse response = httpClient.execute(request);
    return response.getEntity().getContent();
}

Sau đó, bạn lưu trữ hình ảnh dưới dạng Drawable và bạn có thể chuyển nó vào ImageView (thông qua setImageDrawable). Một lần nữa từ đoạn mã trên hãy xem toàn bộ chuỗi.

InputStream is = fetch(urlString);
Drawable drawable = Drawable.createFromStream(is, "src");

Tôi không có DefaultHttpClient trong dự án của mình.
Stepan Yakovenko

8

Có rất nhiều thông tin tốt ở đây ... Gần đây tôi đã tìm thấy một lớp có tên SmartImageView dường như đang hoạt động rất tốt cho đến nay. Rất dễ dàng để kết hợp và sử dụng.

http://loopj.com/android-smart-image-view/

https://github.com/loopj/android-smart-image-view

CẬP NHẬT : Tôi đã kết thúc việc viết một bài đăng trên blog về điều này , vì vậy hãy kiểm tra nó để được trợ giúp về việc sử dụng SmartImageView.

CẬP NHẬT 2ND : Bây giờ tôi luôn sử dụng Picasso cho việc này (xem bên trên) và rất khuyến khích điều đó. :)


7

Đây là một câu trả lời muộn, như đã đề xuất ở trên AsyncTasksẽ và sau khi googling một chút tôi đã tìm thấy một cách khác cho vấn đề này.

Drawable drawable = Drawable.createFromStream((InputStream) new URL("url").getContent(), "src");

imageView.setImageDrawable(drawable);

Đây là chức năng hoàn chỉnh:

public void loadMapPreview () {
    //start a background thread for networking
    new Thread(new Runnable() {
        public void run(){
            try {
                //download the drawable
                final Drawable drawable = Drawable.createFromStream((InputStream) new URL("url").getContent(), "src");
                //edit the view in the UI thread
                imageView.post(new Runnable() {
                    public void run() {
                        imageView.setImageDrawable(drawable);
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

Đừng quên thêm các quyền sau đây AndroidManifest.xmlđể truy cập internet.

<uses-permission android:name="android.permission.INTERNET" />

Tôi đã thử điều này bản thân mình và tôi chưa phải đối mặt với bất kỳ vấn đề nào.


Điều này thực sự rất tốt đẹp cho sự tối giản! Chỉ cần lưu ý rằng cần phải chạy thêm Threadvì luồng UI không cho phép các hoạt động mạng.
creativecreatorormaybenot

6
imageView.setImageBitmap(BitmapFactory.decodeStream(imageUrl.openStream()));//try/catch IOException and MalformedURLException outside

5

Điều này sẽ giúp bạn...

Xác định hình ảnh và tải hình ảnh vào đó .....

Imageview i = (ImageView) vv.findViewById(R.id.img_country);
i.setImageBitmap(DownloadFullFromUrl(url));

Sau đó, xác định phương pháp này:

    public Bitmap DownloadFullFromUrl(String imageFullURL) {
    Bitmap bm = null;
    try {
        URL url = new URL(imageFullURL);
        URLConnection ucon = url.openConnection();
        InputStream is = ucon.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        ByteArrayBuffer baf = new ByteArrayBuffer(50);
        int current = 0;
        while ((current = bis.read()) != -1) {
            baf.append((byte) current);
        }
        bm = BitmapFactory.decodeByteArray(baf.toByteArray(), 0,
                baf.toByteArray().length);
    } catch (IOException e) {
        Log.d("ImageManager", "Error: " + e);
    }
    return bm;
}

4
    String img_url= //url of the image
    URL url=new URL(img_url);
    Bitmap bmp; 
    bmp=BitmapFactory.decodeStream(url.openConnection().getInputStream());
    ImageView iv=(ImageView)findviewById(R.id.imageview);
    iv.setImageBitmap(bmp);

4

Phiên bản có xử lý ngoại lệ và tác vụ không đồng bộ:

AsyncTask<URL, Void, Boolean> asyncTask = new AsyncTask<URL, Void, Boolean>() {
    public Bitmap mIcon_val;
    public IOException error;

    @Override
    protected Boolean doInBackground(URL... params) {
        try {
            mIcon_val = BitmapFactory.decodeStream(params[0].openConnection().getInputStream());
        } catch (IOException e) {
            this.error = e;
            return false;
        }
        return true;
    }

    @Override
    protected void onPostExecute(Boolean success) {
        super.onPostExecute(success);
        if (success) {
            image.setImageBitmap(mIcon_val);
        } else {
            image.setImageBitmap(defaultImage);
        }
    }
};
try {
    URL url = new URL(url);
    asyncTask.execute(url);
} catch (MalformedURLException e) {
    e.printStackTrace();
}

3
    private Bitmap getImageBitmap(String url) {
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
       } catch (IOException e) {
           Log.e(TAG, "Error getting bitmap", e);
       }
       return bm;
    } 

3

Một cách đơn giản và rõ ràng để làm điều này là sử dụng thư viện nguồn mở Prime .


3

Mã này đã được thử nghiệm, nó hoàn toàn hoạt động.

URL req = new URL(
"http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png"
);
Bitmap mIcon_val = BitmapFactory.decodeStream(req.openConnection()
                  .getInputStream());

3

Làm việc cho imageView trong bất kỳ vùng chứa nào, như chế độ xem lưới listview, bố cục bình thường

 private class LoadImagefromUrl extends AsyncTask< Object, Void, Bitmap > {
        ImageView ivPreview = null;

        @Override
        protected Bitmap doInBackground( Object... params ) {
            this.ivPreview = (ImageView) params[0];
            String url = (String) params[1];
            System.out.println(url);
            return loadBitmap( url );
        }

        @Override
        protected void onPostExecute( Bitmap result ) {
            super.onPostExecute( result );
            ivPreview.setImageBitmap( result );
        }
    }

    public Bitmap loadBitmap( String url ) {
        URL newurl = null;
        Bitmap bitmap = null;
        try {
            newurl = new URL( url );
            bitmap = BitmapFactory.decodeStream( newurl.openConnection( ).getInputStream( ) );
        } catch ( MalformedURLException e ) {
            e.printStackTrace( );
        } catch ( IOException e ) {

            e.printStackTrace( );
        }
        return bitmap;
    }
/** Usage **/
  new LoadImagefromUrl( ).execute( imageView, url );

+1 cảm ơn vì giải pháp hoàn chỉnh, dễ dàng.
PeteH

3

Hãy thử cách này, hy vọng điều này sẽ giúp bạn giải quyết vấn đề của bạn.

Ở đây tôi giải thích về cách sử dụng thư viện bên ngoài "AndroidQuery" để tải hình ảnh từ url / máy chủ theo cách asyncTask với hình ảnh được tải trong bộ nhớ cache vào tệp thiết bị hoặc vùng bộ đệm.

  • Tải xuống thư viện "AndroidQuery" từ đây
  • Sao chép / Dán tệp jar này vào thư mục lib của dự án và thêm thư viện này vào đường dẫn xây dựng dự án
  • Bây giờ tôi hiển thị bản demo để sử dụng nó.

Activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/imageFromUrl"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"/>
            <ProgressBar
                android:id="@+id/pbrLoadImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"/>

        </FrameLayout>
    </LinearLayout>

MainActivity.java

public class MainActivity extends Activity {

private AQuery aQuery;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    aQuery = new AQuery(this);
    aQuery.id(R.id.imageFromUrl).progress(R.id.pbrLoadImage).image("http://itechthereforeiam.com/wp-content/uploads/2013/11/android-gone-packing.jpg",true,true);
 }
}

Note : Here I just implemented common method to load image from url/server but you can use various types of method which can be provided by "AndroidQuery"to load your image easily.

3

Truy vấn Android có thể xử lý việc đó cho bạn và hơn thế nữa (như bộ nhớ cache và tiến trình tải).

Hãy nhìn vào đây .

Tôi nghĩ là cách tiếp cận tốt nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.