Jak załadować ImageView według adresu URL w Androidzie? [Zamknięte]


530

Jak korzystasz z obrazu, do którego odwołuje się adres URL ImageView?



Odpowiedzi:


713

Od programisty Androida :

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

Upewnij się, że masz ustawione następujące uprawnienia AndroidManifest.xmldostępu do Internetu.

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

39
To jest niesamowite. I powinno być znacznie wyżej na liście. Asynctask umożliwia ładowanie bez zamrażania interfejsu użytkownika!
Kyle Clegg,

3
AsyncTasks używa szeregowego modułu wykonującego, co oznacza, że ​​każdy obraz ładuje się jeden po drugim i nie wykonuje równoległego ładowania wątków.
Blundell

2
Link źródłowy już nie działa ...
hecvd

10
Strumień wejściowy nie jest zamknięty w twoim przykładzie. Najlepiej zrobić w ostatnim bloku twojego try / catch.
Risadinha,

2
Czy ta metoda jest nadal aktualna? Jestem trochę zdezorientowany co do metody OnClick () i jej celu
tccpg288

170

1. Picasso umożliwia bezproblemowe ładowanie obrazu w aplikacji - często w jednym wierszu kodu!

Użyj Gradle:

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

Tylko jedna linia kodu!

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

2. Szybkość Biblioteka ładowania i buforowania obrazu dla Androida skupia się na płynnym przewijaniu

Użyj Gradle:

repositories {
  mavenCentral() 
  google()
}

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

// Dla prostego widoku:

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

3. Fresk to potężny system do wyświetlania obrazów w aplikacjach na Androida. Fresk dba o ładowanie i wyświetlanie obrazów, więc nie musisz.

Pierwsze kroki z Fresco


2
Więc jeśli adres URL to localhost, oznacza to, że obraz znajduje się w bazie danych serwera lokalnego rozwijającego się systemu, np. Xampp, nadal mogę pobrać obraz z adresu URL =.
blackjack

2
@blackjack - localhost z aplikacji byłby samym smartfonem. Aby uzyskać dostęp do rozwijającego się systemu, smartfon i rozwijający się system będą musiały znajdować się w tej samej sieci i będziesz musiał użyć adresu IP swojego rozwijającego się systemu w tej sieci.
Ridcully,

1
czy można użyć Picassa do załadowania obrazu na przycisku?
mahdi,

1
@chiragkyada próbuję z tym kodem Picasso.with (kontekst) .load (url) .into (widok_przycisku); ale wyświetla błąd dla: do (widok_przycisku)
mahdi

1
Myślę, że to powinna być zaakceptowana odpowiedź
Udo,

150

Najpierw musisz pobrać obraz

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

Następnie użyj Imageview.setImageBitmap, aby ustawić bitmapę w ImageView


126
masz rację. ale tylko te 3 linie pomagają rozwiązać problem. URL newurl = nowy adres URL (photo_url_str); mIcon_val = BitmapFactory.decodeStream (newurl.openConnection () .getInputStream ()); profile_photo.setImageBitmap (mIcon_val); dziękuję za twoją odpowiedź.
Praveen

2
W przypadku adresu URL - import java.net.URL; prywatny statyczny końcowy int IO_BUFFER_SIZE = 4 * 1024; jaki był ostatni?
Steve


@SACPK powinieneś napisać swój komentarz jako odpowiedź, aby mógł zostać poddany głosowaniu
Jim Wallace

odpowiedź była dla mnie odpowiednia ,, opublikuj jako odpowiedź :)
omnia Mm

71

Napisałem klasę, aby sobie z tym poradzić, ponieważ wydaje się, że jest to powtarzająca się potrzeba w moich różnych projektach:

https://github.com/koush/UrlImageViewHelper

UrlImageViewHelper wypełni ImageView obrazem znalezionym pod adresem URL.

Próbka przeprowadzi wyszukiwanie grafiki Google i załaduje / pokaż wyniki asynchronicznie.

UrlImageViewHelper automatycznie pobierze, zapisze i zbuforuje wszystkie adresy URL obrazów BitmapDrawables. Zduplikowane adresy URL nie zostaną załadowane dwukrotnie do pamięci. Pamięć bitmapowa jest zarządzana przy użyciu słabej referencyjnej tabeli skrótów, więc gdy tylko obraz nie będzie już używany, zostanie automatycznie wyrzucony.


Przy okazji, jaka jest licencja?
Ehtesh Choudhury,

@Shurane - Apache. Zanotuję to później.
koush

1
Wydaje się, że musimy użyć tego zamiast github.com/koush/ion, ponieważ UrlImageViewHelper został wycofany, jak pokazano na stronie projektu github pod adresem github.com/koush/UrlImageViewHelper .
Svetoslav Marinov,

69

W każdym razie ludzie proszą mój komentarz o opublikowanie go jako odpowiedzi. piszę.

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

to jest krótkie i świetne, dzięki
Nactus

18
mm .. nie można tego zrobić z wątku interfejsu użytkownika.
Guy

2
W przypadku osób, które mają problemy z „Wyjątkiem zniekształconego adresu URL”, otocz powyższe linie w try / catch. stackoverflow.com/a/24418607/2093088
Riot Goes Woof

1
Należy to zrobić za pomocą AsyncTask, jak opisano powyżej
B-GangsteR

63

Przyjęta powyżej odpowiedź jest świetna, jeśli ładujesz obraz na podstawie kliknięcia przycisku, ale jeśli robisz to w nowej aktywności, zawiesza interfejs użytkownika na sekundę lub dwie. Rozglądając się, zauważyłem, że prosta asynchronizacja wyeliminowała ten problem.

Aby użyć asynctask, dodaj tę klasę na końcu swojej aktywności:

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

I wywołaj z metody onCreate (), używając:

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

Rezultatem jest szybko wczytana aktywność i podgląd obrazu, który pokazuje ułamek sekundy później w zależności od prędkości sieci użytkownika.


To było szybkie i kompaktowe. Ładnie spełniło moje potrzeby! Dzięki!
Mark Murphy,

od mojego znacznika czasu, zadziałało to dla mnie!
Carpk

25

Możesz także użyć tego widoku LoadingImageView, aby załadować obraz z adresu URL:

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

Po dodaniu pliku klasy z tego łącza można utworzyć instancję widoku obrazu adresu URL:

w 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"
 />

W kodzie:

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

I zaktualizuj za pomocą:

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

Ładna próbka, ale nie sądzę, że jest to bezpieczne dla wątków. Próbuję użyć go w Async na onPostExecute, jednak onPostExecute może czasem zakończyć się przed otrzymaniem wywołania zwrotnego renderując pusty obraz.
Jimmy

To zarządza własnym wątkiem. Dlaczego więc nie poprosić ASyncTask o oddzwonienie do interfejsu użytkownika, gdy zakończy się, z wybranym adresem URL. W ten sposób nie masz nici spawnujących wątki.
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;
}
}

Bardzo dziękuję, idealny przykład, którego szukałem ................, ale w złym temacie
VenomVendor

10

Cześć Mam najłatwiejszy kod, spróbuj tego

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

main.xml

  <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"/>

Spróbuj tego


10

Moim zdaniem najlepsza współczesna biblioteka do takiego zadania to Picasso by Square. Pozwala załadować obraz do ImageView według adresu URL za pomocą jednej linijki:

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

9

Niedawno znalazłem tutaj wątek , ponieważ muszę zrobić podobną rzecz dla widoku listy z obrazami, ale zasada jest prosta, jak można przeczytać w pierwszej pokazanej tam klasie próbki (autorstwa Jleedev). Otrzymujesz strumień wejściowy obrazu (z sieci)

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

Następnie przechowujesz obraz jako Drawable i możesz przekazać go do ImageView (przez setImageDrawable). Znów z górnego fragmentu kodu spójrz na cały wątek.

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

W moim projekcie nie ma DefaultHttpClient.
Stepan Jakowenko

8

Wiele dobrych informacji tutaj ... Niedawno znalazłem klasę o nazwie SmartImageView, która jak dotąd wydaje się działać naprawdę dobrze. Bardzo łatwy do włączenia i użytkowania.

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

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

AKTUALIZACJA : Skończyło się na tym , że napisałem post na blogu , więc sprawdź ją, aby uzyskać pomoc na temat korzystania ze SmartImageView.

2ND UPDATE : Teraz zawsze używam do tego Picassa (patrz wyżej) i bardzo go polecam. :)


7

To jest późna odpowiedź, jak sugeruje to powyżej AsyncTask, a po googlowaniu znalazłem jeszcze jeden sposób na rozwiązanie tego problemu.

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

imageView.setImageDrawable(drawable);

Oto pełna funkcja:

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

Nie zapomnij dodać następujących uprawnień w AndroidManifest.xmlcelu uzyskania dostępu do Internetu.

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

Próbowałem tego sam i nie mam jeszcze żadnych problemów.


To jest naprawdę bardzo miłe dla minimalizmu! Pamiętaj tylko, że należy uruchomić dodatkowo, Threadponieważ wątek interfejsu użytkownika nie pozwala na operacje sieciowe.
creativecreatorormaybenot

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

5

Pomoże ci to ...

Zdefiniuj podgląd obrazu i załaduj do niego obraz .....

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

Następnie Zdefiniuj tę metodę:

    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

Wersja z obsługą wyjątków i zadaniem asynchronicznym:

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

Ten kod jest testowany, działa całkowicie.

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

Praca dla imageView w dowolnym kontenerze, takim jak widok siatki widoku listy, normalny układ

 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 dzięki za kompletne, łatwe rozwiązanie.
PeteH

3

Spróbuj w ten sposób, mam nadzieję, że pomoże ci to rozwiązać problem.

Tutaj wyjaśniam, jak używać biblioteki zewnętrznej „AndroidQuery” do ładowania obrazu z adresu URL / serwera w sposób asynchroniczny, a także załadować obraz z pamięci podręcznej do pliku urządzenia lub obszaru pamięci podręcznej.

  • Pobierz bibliotekę „AndroidQuery” stąd
  • Skopiuj / Wklej ten słoik do folderu lib projektu i dodaj tę bibliotekę do ścieżki kompilacji projektu
  • Teraz pokazuję demo, jak z niego korzystać.

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

Android Query poradzi sobie z tym i wiele innych (takich jak pamięć podręczna i postęp ładowania).

Spójrz tutaj .

Myślę, że to najlepsze podejście.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.