webentwicklung-frage-antwort-db.com.de

Retrofit API zum Abrufen eines PNG-Bildes

Hallo, ich bin neu bei Retrofit Framework für Android. Ich könnte JSON-Antworten von REST Diensten erhalten, die es verwenden, aber ich weiß nicht, wie ich ein PNG mit Retrofit herunterladen kann. Ich versuche, das PNG von dieser URL herunterzuladen: http: //wwwns.akamai.com/media_resources/globe_emea.png . Was soll das Antwortobjekt sein, das im Callback <> angegeben werden muss, um dies zu erreichen.

27
Pradeep CR

Wie bereits erwähnt, sollten Sie Retrofit nicht verwenden, um das Bild selbst herunterzuladen. Wenn Sie den Inhalt einfach herunterladen möchten, ohne ihn anzuzeigen, können Sie einfach einen HTTP-Client wie OkHttp verwenden, der eine andere Bibliothek von Square ist.

Hier sind einige Codezeilen, mit denen Sie dieses Bild herunterladen können. Sie könnten dann die Daten aus dem InputStream lesen.

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url("http://wwwns.akamai.com/media_resources/globe_emea.png")
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Request request, IOException e) {
            System.out.println("request failed: " + e.getMessage());
        }

        @Override
        public void onResponse(Response response) throws IOException {
            response.body().byteStream(); // Read the data from the stream
        }
    });

Auch wenn Retrofit nicht der richtige Ansprechpartner für Ihre Frage ist, würde die Signatur Ihrer Schnittstellendefinition dies begrüßen. Aber tu das nicht nochmal.

public interface Api {
    @GET("/media_resources/{imageName}")
    void getImage(@Path("imageName") String imageName, Callback<Response> callback);
}
34
Miguel Lavigne

Natürlich verwenden wir normalerweise Picasso, um das Bild zu laden, aber manchmal müssen wir Nachrüsten verwenden, um ein spezielles Bild zu laden (wie das Abrufen eines Captcha-Bildes), für das Sie einen Header hinzufügen müssen request, erhalten Sie einen Wert aus dem Header der Antwort (natürlich können Sie auch Picasso + OkHttp verwenden, aber in einem Projekt haben Sie Retrofit bereits verwendet, um die meisten Netzanforderungen zu verarbeiten) bereits in meinem Projekt implementiert).

Der entscheidende Punkt ist, dass Sie okhttp3.ResponseBody Verwenden müssen, um eine Antwort zu erhalten. Andernfalls analysiert Retrofit die Antwortdaten als JSON und nicht als Binärdaten.

codes:

public interface Api {
    // don't need add 'Content-Type' header, it's useless
    // @Headers({"Content-Type: image/png"})
    @GET
    Call<ResponseBody> fetchCaptcha(@Url String url);
}

Call<ResponseBody> call = api.fetchCaptcha(url);
call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.isSuccessful()) {
                if (response.body() != null) {
                    // display the image data in a ImageView or save it
                    Bitmap bmp = BitmapFactory.decodeStream(response.body().byteStream());
                    imageView.setImageBitmap(bmp);
                } else {
                    // TODO
                }
            } else {
                // TODO
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            // TODO
        }
    });
29
Spark.Bao

Retrofit ist eine REST Bibliothek, Sie können Retrofit nur verwenden, um die Bild-URL abzurufen, aber zum Anzeigen des Bildes sollten Sie Picasso verwenden: http://square.github.io/picasso/

15
Yuraj

Deklarieren Sie es als Rückruf, zum Beispiel:

@GET("/api/{api}/bla/image.png")
Call<ResponseBody> retrieveImageData();

dann konvertiere es selbst nach Bitmap:

ResponseBody body = retrofitService.retrieveImageData().execute().body();
        byte[] bytes = body.bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
11

Sie können auch Retrofit verwenden, um den @GET Durchzuführen und einfach den Response zurückzugeben. Dann können Sie im Code isr = new BufferedInputStream(response.getBody().in()) ausführen, um den Eingabestream des Bildes abzurufen und in eine Bitmap zu schreiben, indem Sie BitmapFactory.decodeStream(isr) ausführen.

3
astryk

Einzelheiten

  • Android Studio 3.1.4
  • Kotlin 1.2.60
  • Nachrüstung 2.4.0
  • in minSdkVersion 19 eingecheckt

Lösung

objekt RetrofitImage

object RetrofitImage {

    private fun provideRetrofit(): Retrofit {
        return Retrofit.Builder().baseUrl("https://google.com").build()
    }

    private interface API {
        @GET
        fun getImageData(@Url url: String): Call<ResponseBody>
    }

    private val api : API by lazy  { provideRetrofit().create(API::class.Java) }

    fun getBitmapFrom(url: String, onComplete: (Bitmap?) -> Unit) {

        api.getImageData(url).enqueue(object : retrofit2.Callback<ResponseBody> {

            override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
                onComplete(null)
            }

            override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
                if (response == null || !response.isSuccessful || response.body() == null || response.errorBody() != null) {
                    onComplete(null)
                    return
                }
                val bytes = response.body()!!.bytes()
                onComplete(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
            }
        })
    }
}

Verwendungszweck 1

RetrofitImage.getBitmapFrom(ANY_URL_STRING) {
   // "it" - your bitmap
   print("$it")
}

Verwendung 2

Erweiterung für ImageView

fun ImageView.setBitmapFrom(url: String) {
    val imageView = this
    RetrofitImage.getBitmapFrom(url) {
        val bitmap: Bitmap?
        bitmap = if (it != null) it else {
            // create empty bitmap
            val w = 1
            val h = 1
            val conf = Bitmap.Config.ARGB_8888
            Bitmap.createBitmap(w, h, conf)
        }

        Looper.getMainLooper().run {
            imageView.setImageBitmap(bitmap!!)
        }
    }
}

Verwendung der Erweiterung

imageView?.setBitmapFrom(ANY_URL_STRING)
3

Ich hoffe, der folgende Code wird Ihnen helfen:

Fügen Sie folgende Funktion in MainActivity.Java Ein:

void getRetrofitImage() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    RetrofitImageAPI service = retrofit.create(RetrofitImageAPI.class);

    Call<ResponseBody> call = service.getImageDetails();

    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {

            try {

                Log.d("onResponse", "Response came from server");

                boolean FileDownloaded = DownloadImage(response.body());

                Log.d("onResponse", "Image is downloaded and saved ? " + FileDownloaded);

            } catch (Exception e) {
                Log.d("onResponse", "There is an error");
                e.printStackTrace();
            }

        }

        @Override
        public void onFailure(Throwable t) {
            Log.d("onFailure", t.toString());
        }
    });
}

Es folgt der Dateibearbeitungscode für das Bild:

private boolean DownloadImage(ResponseBody body) {

        try {
            Log.d("DownloadImage", "Reading and writing file");
            InputStream in = null;
            FileOutputStream out = null;

            try {
                in = body.byteStream();
                out = new FileOutputStream(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
                int c;

                while ((c = in.read()) != -1) {
                    out.write(c);
                }
            }
            catch (IOException e) {
                Log.d("DownloadImage",e.toString());
                return false;
            }
            finally {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            }

            int width, height;
            ImageView image = (ImageView) findViewById(R.id.imageViewId);
            Bitmap bMap = BitmapFactory.decodeFile(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
            width = 2*bMap.getWidth();
            height = 6*bMap.getHeight();
            Bitmap bMap2 = Bitmap.createScaledBitmap(bMap, width, height, false);
            image.setImageBitmap(bMap2);

            return true;

        } catch (IOException e) {
            Log.d("DownloadImage",e.toString());
            return false;
        }
    }

Dies geschieht mit Android Retrofit 2.0. Ich hoffe, es hat Ihnen geholfen.

Quelle: Image-Download mit Retrofit 2.

2
Navneet Goel

Retrofit kodiert Ihr Byte-Array auf Basis 64. Dekodieren Sie also Ihren String und Sie können loslegen. Auf diese Weise können Sie eine Liste von Bildern abrufen.

public static Bitmap getBitmapByEncodedString(String base64String) {
    String imageDataBytes = base64String.substring(base64String.indexOf(",")+1);
    InputStream stream = new ByteArrayInputStream(Base64.decode(imageDataBytes.getBytes(), Base64.DEFAULT));
    return BitmapFactory.decodeStream(stream);
}
0
Ghita Tomoiaga