Подтвердить что ты не робот

Retrofit API для извлечения png-изображения

Привет, я новичок в Retrofit framework для Android. Я могу получить ответы JSON от служб REST, используя это, но я не знаю, как загрузить png с помощью модифицированной версии. Я пытаюсь загрузить png из этого URL:  http://wwwns.akamai.com/media_resources/globe_emea.png. Каким должен быть ответ Object, который будет указан в Callback < > для достижения этого.

4b9b3361

Ответ 1

Как уже упоминалось, вы не должны использовать Retrofit для фактического скачивания самого изображения. Если ваша цель - просто загрузить контент без его отображения, вы можете просто использовать клиент Http, например OkHttp, который является еще одним из квадратных библиотек.

Вот несколько строк кода, которые бы вы загрузили это изображение. Затем вы можете прочитать данные из 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
        }
    });

Несмотря на то, что Retrofit не является мужчиной для задания, чтобы ответить на ваш вопрос, вам понравится подпись вашего интерфейса. Но опять же не делайте этого.

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

Ответ 2

Конечно, мы обычно используем Picasso для загрузки изображения, но иногда нам действительно нужно использовать Retrofit для загрузки специального изображения (например, получить изображение с картинки), вам нужно добавить заголовок для запроса, получить некоторое значение из заголовка ответа (конечно, вы можете также используйте Picasso + OkHttp, но в проекте вы уже использовали Retrofit для обработки большинства сетевых запросов), поэтому здесь рассмотрим, как реализовать Retrofit 2.0.0 (я уже реализовал в своем проекте).

Ключевым моментом является то, что вам нужно использовать okhttp3.ResponseBody для получения ответа, иначе Retrofit будет анализировать данные ответа как JSON, а не двоичные данные.

коды:

public interface Api {
    // don't need add 'Content-Type' header, it 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
        }
    });

Ответ 3

Retrofit - это библиотека REST, вы можете использовать Retrofit только для получения URL-адреса изображения, но для отображения изображения вы должны использовать Picasso: http://square.github.io/picasso/

Ответ 4

Объявите, что он возвращает вызов:

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

затем преобразуйте его в Bitmap самостоятельно:

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

Ответ 5

Вы также можете использовать Retrofit для выполнения @GET и просто вернуть Response. Затем в коде вы можете сделать isr = new BufferedInputStream(response.getBody().in()), чтобы получить входной поток изображения и записать его в растровое изображение, например, выполнив BitmapFactory.decodeStream(isr).

Ответ 6

Надеюсь, следующий код вам поможет:

Включить следующую функцию внутри 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());
        }
    });
}

Ниже приведен код обработки файлов для изображения:

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

Это делается с помощью Android Retrofit 2.0. Надеюсь, это вам помогло.

Источник: Загрузка изображения с помощью Retrofit 2.0

Ответ 7

подробности

  • Студия Android 3.1.4
  • Котлин 1.2.60
  • Дооснащение 2.4.0
  • проверено в minSdkVersion 19

Решение

объект 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))
            }
        })
    }
}

Использование 1

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

Использование 2

Расширение для 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!!)
        }
    }
}

Использование расширения

imageView?.setBitmapFrom(ANY_URL_STRING)

Ответ 8

Модификация кодирует ваш байтовый массив в базу 64. Так что декодируйте вашу строку, и все готово. Таким образом, вы можете получить список изображений.

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