Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving remote jpg without the need to go from jpg->bitmap->jpg #1025

Closed
lokewate opened this issue May 16, 2015 · 7 comments
Closed

Saving remote jpg without the need to go from jpg->bitmap->jpg #1025

lokewate opened this issue May 16, 2015 · 7 comments

Comments

@lokewate
Copy link

When a jpg is downloaded from a server using load(url).into(target), target only allows for accessing the image using a Bitmap through onBitmapLoaded(). However, if we want to save this image locally, then the bitmap needs to be converted to a jpg, which would cause quality loss. There should be a way to save the downloaded data directly.

@jacobtabak
Copy link
Contributor

I would suggest you download the image first using okhttp and then load it from disk using Picasso. This type of feature doesn't really make sense to duplicate in Picasso.

@dnkoutso
Copy link
Collaborator

Custom Downloader will give you access to the InputStream. Disk cache is completely transparent to Picasso.

You cannot attach a custom downloader per request at the moment, if that is what you are trying to achieve, you are better off with a different implementation to achieve this.

@lokewate
Copy link
Author

@jacobtabak: Just to clarify, I am downloading images on demand when the user swipes through a fullscreen view. What you are suggesting is that in the PagerAdapter's instantiateItem() method, I set a placeholder image and then trigger an AsyncTask that will take the ImageView object, and download the image using okhttp and use Picasso to then set the downloaded image to the ImageView. Is there any pitfalls in this approach related to lifecycle of ImageView?

@JakeWharton
Copy link
Member

Dupe #506

@jacobtabak
Copy link
Contributor

@lokewate I'd probably do it like this until official support is added:

  1. Inject an OkHttpClient with a disk cache into your Picasso instance using Picasso.Builder
  2. Load an image using Picasso normally (don't do what you said above)
  3. Use the same OkHttpClient instance to download the image to file. It should be cached.

Here's some code to download a file with okhttp/okio -

    Request request = new Request.Builder().url("http://test.com/image.jpg").build();
    okHttpClient.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Request request, IOException e) {
        // handle failure
      }

      @Override public void onResponse(Response response) throws IOException {
        File outputFile = new File(getCacheDir(), "tmp.jpg");
        response.body().source().readAll(Okio.sink(outputFile));
      }
    });

@JakeWharton
Copy link
Member

response.body().source().readAll(Okio.sink(outputFile));

should be

BufferedSource source = response.body().source()
Sink sink = Okio.sink(file);
source.readAll(sink);
source.close();
sink.close();

and those close calls should probably be in a finally block.

@lokewate
Copy link
Author

Thanks all for the interim solution. Just to clarify, this is how I created the Picasso object.

OkHttpClient okHttpClient = new OkHttpClient();
OkHttpDownloader okHttpDownloader = new OkHttpDownloader(okHttpClient);
Picasso picasso = new Picasso.Builder(context).downloader(okHttpDownloader).build();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants