Adaptation de L'API pour récupérer une image png

Salut je suis nouveau pour Retrofit framework pour Android. Je pourrais obtenir des réponses JSON des services de repos en l'utilisant, Mais je ne sais pas comment télécharger un png en utilisant retrofit. Je suis en train de télécharger le fichier png à partir de cette url: http://wwwns.akamai.com/media_resources/globe_emea.png<!--2. Quel devrait être l'objet de réponse à spécifier dans le Callback pour réaliser ceci.

16
demandé sur Pradeep CR 2014-08-23 17:37:15

7 réponses

comme mentionné, vous ne devriez pas utiliser Retrofit pour télécharger l'image elle-même. Si votre objectif est tout simplement de télécharger le contenu sans l'afficher ensuite, vous pouvez simplement utiliser un client Http comme OkHttp qui est une autre des bibliothèques de Square.

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

même si Retrofit n'est pas l'homme pour le travail de répondre à votre question, la signature de votre définition D'Interface voudrait ceci. Mais encore une fois de ne pas le faire.

public interface Api {
    @GET("/media_resources/{imageName}")
    void getImage(@Path("imageName") String imageName, Callback<Response> callback);
}
25
répondu Miguel Lavigne 2014-08-23 14:55:00

bien sûr nous utilisons habituellement Picasso pour charger l'image, mais parfois nous avons vraiment besoin D'utiliser Retrofit pour charger une image spéciale (comme fetch a captcha image), vous avez besoin d'ajouter un en-tête pour la requête, obtenir une certaine valeur de l'en-tête de réponse (bien sûr, vous pouvez également utiliser Picasso + OkHttp, mais dans un projet, vous avez déjà utilisé Retrofit pour traiter la plupart des requêtes net), alors voici comment mettre en œuvre par Retrofit 2.0.0 (j'ai déjà mis en œuvre dans mon projet).

Le point clé est que vous besoin d'utiliser okhttp3.ResponseBody pour recevoir de réponse, sinon Rénovation va analyser les données de réponse en JSON, pas de données binaires.

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
                    Bitmpa bm = BitmapFactory.decodeStream(response.body().byteStream());
                    ivCaptcha.setImageBitmap(bm);
                } else {
                    // TODO
                }
            } else {
                // TODO
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            // TODO
        }
    });
19
répondu Spark.Bao 2016-04-06 03:43:31

Rénovation est un RESTE de la bibliothèque, vous pouvez utiliser la Rénovation que pour obtenir l'URL de l'image mais pour l'affichage de l'Image, vous devez utiliser Picasso: http://square.github.io/picasso/

14
répondu Yuraj 2014-08-23 13:49:27

Déclarer retour d'Appel par exemple:

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

puis convertissez-le en Bitmap vous-même:

ResponseBody body = retrofitService.retrieveImageData().execute().body();
        byte[] bytes = body.bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
5
répondu Alécio Carvalho 2016-12-30 10:59:34

vous pouvez également utiliser Retrofit pour effectuer le @GET et il suffit de retourner le Response. Puis en code vous pouvez faire isr = new BufferedInputStream(response.getBody().in()) pour obtenir le flux d'entrée de l'image et de l'écrire dans une image, disons, en faisant BitmapFactory.decodeStream(isr).

3
répondu astryk 2015-02-26 03:42:23

j'espère code suivant va vous aider:

incluez la fonction suivante à l'intérieur de MainActivity.java:

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

voici le code de gestion de fichier pour l'image:

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

cela se fait en utilisant Android Retrofit 2.0. J'espère que cela vous a aidé.

Source: télécharger L'Image en utilisant Retrofit 2.0

1
répondu Navneet Goel 2017-06-22 10:40:45

Détails

  • Android studio 3.1.4
  • Kotlin 1.2.60
  • Rénovation 2.4.0
  • vérifié dans minSdkVersion 19

Solution

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

Utilisation 1

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

Utilisation 2

Extension pour 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!!)
        }
    }
}

Utilisation de l'extension

imageView?.setBitmapFrom(ANY_URL_STRING)
1
répondu Vasily Bodnarchuk 2018-09-16 22:41:21