Search code examples
javaandroidimagepicassoimage-resizing

Picasso performance issues when resizing multiple images


I have an activity that need to load multiples images and resize them so that they fit screen width.

I try to load the images into this.frameHolder which is a LinearLayout inside a NestedScrollView and do match the screen width.

The code below is working but make the application very slow as soon as there is more than few images.

    public void displayImages(List<ImageContent> images) {
        for(ImageContent img:images) {
            //Create an new view for image
            ImageView imgView = new ImageView(this);
            this.frameHolder.addView(imgView);

            //Create a client with custom header for this image
            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(chain -> {
                        Request.Builder newRequest = chain.request().newBuilder();
                        newRequest.addHeader(img.getHeaderKey(), img.getHeaderValue());
                        return chain.proceed(newRequest.build());
                    }).build();
            
            //Create a picasso instance for this client
            Picasso.Builder builder = new Picasso.Builder(this).downloader(new OkHttp3Downloader(client));
            Picasso pic = builder.build();

            //Load and resize the image to fit screen width
            pic.load(img.getUrlContentData()).resize(frameHolder.getWidth(), 0).into(imgView);
        }
    }

How can I load multiple images and make them fit the screen width, without degrading performance too much ? I'm open to other solution than Picasso if that make it possible.


Solution

  • I ended giving up on using a library, as @Qasim Malik suggested I've tried Glide and Fresco as alternatives, but I still got similar issues.

    So since I wasn't able to do it with a library, I did it myself by handling the request and image resizing directly :

    private final static OkHttpClient client = new OkHttpClient();
    public void displayImages(List<ImageContent> images) {
            for(ImageContent img:images) {
                ImageView imgView = new ImageView(this);
                this.frameHolder.addView(imgView);
    
                Request.Builder requestBuilder = new Request.Builder()
                    .addHeader(img.getHeaderKey(), img.getHeaderValue())
                    .url(content.getUrlContentData());
    
    
                client.newCall(requestBuilder.build()).enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        loadFailed();
                    }
    
                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
                        float widthInitial =  bitmap.getWidth() ;
                        float heightInitial =  bitmap.getHeight() ;
                        Bitmap resizedImage = Bitmap.createScaledBitmap(bitmap, frameHolder.getWidth(), Math.round(frameHolder.getWidth() * (heightInitial / widthInitial)), true);
                        
                        imgView.setImageBitmap(resizedImage);
                    }
            });
            }
        }
    

    This work fine, and there are no more performance issues, but I'm still unsure of why the libraries are so slow at it...