web-dev-qa-db-fra.com

API de mise à niveau pour récupérer une image png

Salut, je suis nouveau dans le cadre Retrofit pour Android. Je pourrais obtenir des réponses JSON de REST services l'utilisant mais je ne sais pas comment télécharger un png en utilisant la modification. J'essaie de télécharger le png à partir de cette URL: http: //wwwns.akamai.com/media_resources/globe_emea.png . Quel devrait être l'objet de réponse à spécifier dans le rappel <> pour y parvenir.

27
Pradeep CR

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

Voici quelques lignes de code qui vous permettraient de télécharger cette image. Vous pouvez ensuite lire les données de InputStream.

    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 du travail pour répondre à votre question, la signature de votre définition d'interface le souhaiterait. Mais encore une fois, ne faites pas ça.

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

Bien sûr, nous utilisons généralement Picasso pour charger l'image, mais parfois nous avons vraiment besoin d'utiliser Retrofit pour charger une image spéciale (comme récupérer une image captcha), vous devez ajouter un en-tête pour demande, obtenez une certaine valeur de l'en-tête de la réponse (bien sûr, vous pouvez également utiliser Picasso + OkHttp, mais dans un projet, vous avez déjà utilisé Retrofit pour gérer la plupart des demandes nettes), alors voici ici comment mettre en œuvre par Retrofit 2.0.0 (I ont déjà mis en œuvre dans mon projet).

Le point clé est que vous devez utiliser okhttp3.ResponseBody pour recevoir la réponse, sinon Retrofit analysera les données de réponse en JSON, et non en 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
                    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 est une bibliothèque REST, vous pouvez utiliser Retrofit uniquement pour obtenir l'URL de l'image, mais pour afficher l'image, vous devez utiliser Picasso: http://square.github.io/picasso/

15
Yuraj

Déclarez-le renvoyant l'appel par exemple:

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

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

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

Vous pouvez également utiliser Retrofit pour effectuer le @GET Et renvoyer simplement le Response. Ensuite, dans le code, vous pouvez faire isr = new BufferedInputStream(response.getBody().in()) pour obtenir le flux d'entrée de l'image et l'écrire dans un bitmap, par exemple, en faisant BitmapFactory.decodeStream(isr).

3
astryk

Détails

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

Solution

object 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!!)
        }
    }
}

tilisation de l'extension

imageView?.setBitmapFrom(ANY_URL_STRING)
3
Vasily Bodnarchuk

J'espère que le code suivant vous aidera:

Inclure la fonction suivante dans 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échargement d'images à l'aide de Retrofit 2.

2
Navneet Goel

Retrofit est en train d'encoder votre tableau d'octets en base 64. Décodez donc votre chaîne et vous êtes prêt à partir. De cette façon, vous pouvez récupérer une liste d'images.

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