Store images in picasso with a cache key of our own - android

Is there a way I can load images into Picasso's image cache by specifying the cache key that is used ?
On a side note if that is not possible, I have made the necessary changes but I am not sure how to rebuild the jar. Any instructions to rebuild Picasso are much appreciated.

You can call stableKey on your requestCreator object.
https://square.github.io/picasso/2.x/picasso/com/squareup/picasso/RequestCreator.html#stableKey-java.lang.String-
It will be like:
Picasso.with(context).load(yourURL).stableKey(yourKey).into(textView);

I not found no public access to this functionality, but for me works this workaround:
//1. Init picasso, create cache
mCache = new LruCache(mContext);
mPicasso = new Picasso.Builder(mContext).memoryCache(mCache).build();
//2. Load bitmap
mPicasso.load(uri).resize(mThumbWidth, mThumbHeight).centerCrop().into(v, callback);
//3. In case of error (for example, in callback), you can manually download the picture and store to cache
Bitmap bmp = <custom load>
//make key
StringBuilder sb = new StringBuilder(uri);
sb.append("\nresize:").append(mThumbWidth).append("x").append(mThumbHeight).append("\ncenterCrop\n");
mCache.set(sb.toString(), bmp);
Please note, that a key is used uri and your custom transformation (resize, centerCrop ant such, see more at com.squareup.picasso.Utils#createKey)

this worked for me
String strUrl = WWW.sultan.com....;
Bitmap = bitmap;
Picasso.with(Profile.this).load(strUrl).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
userImage.setImageBitmap(bitmap);
this.bitmap = bitmap; //this can be used any where in the code
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});

Related

Android Ion library load bitmap image

How can load images from an url with ion ? Image should be a bitmap.
Example: Bitmap image=Ion.with(this).load('url')
How can I achive this ?
Library:https://github.com/koush/ion
You should probably do it asynchronously. Here is an example:
Ion.with(this).load("url").withBitmap().asBitmap()
.setCallback(new FutureCallback<Bitmap>() {
#Override
public void onCompleted(Exception e, Bitmap result) {
// do something with your bitmap
}
});
It can also be loaded synchronously if needed. For example:
Bitmap image = Ion.with(this)
.load("url")
.withBitmap()
.asBitmap()
.get();

AQuery: How to download images in non-sequential manner without any reference to imageView in the aQuery call

Question 1: Is it possible to download image file without giving the reference to ImageView?
Question 2: Can i download each file in a separage instance of aQuery or do i have to download the file sequentially? e.g, waiting for the callback of current file download and then trigger the next file download call? Below is my code
// Ad is my custom model class
// adList is my list of Ads having URL's to the ads hosted somewhere
// imageView is an invisible imageView as downloading does not start if i don't give any reference to any imageView resource
for (String adUrl : adList) {
if (adUrl.length() > 0) {
AQuery aQuery = new AQuery(DownloadAdActivity.this);
BitmapAjaxCallback callback = new BitmapAjaxCallback();
callBack.url(adUrl);
callBack.fallback(R.id.placeHolderResource);
callBack.fileCache(true);
callBack.memCache(true);
aQuery.id(imageView).image(callBack);
}
}
I need to download 20/30 images when the app starts first time, so far i am doing it by giving a hidden imageView reference and trigging the aQuery sequentially after each image has downloaded. I tried to generate 20/30 request in a loop but only the last aQuery trigger call works which cancels the previous image download call.
Please guide me:
1- How to cache images without giving any reference to the imageView
2- How to download images in parallel manner, not in sequential manner through AQuery.
1) You can use ajax call without ImageView reference to download image.
androidQuery.ajax("url", Bitmap.class, 0, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap bitmap, AjaxStatus status) {
super.callback(url, bitmap, status);
}
});
2) By default you can download 4 images concurrently. But you can change as per your requirement like this
AjaxCallback.setNetworkLimit(8);
You can use Picasso
It will make all the downloads and also the caching for the images.
Anyway if the images are quite small you should prepare a "zip" file and dl all of them with an AsyncTask / Thread and unzip them. Opening and closing the connections to the server are "very expensive" operations in time consuming.
Here is method to obtain bitmap from url using AQuery
static Bitmap myBitmap = null;
public static Bitmap getBitmapFromURL(String src) {
try {
Log.i(TAG, "Image Url is : " + src);
AQuery androidQuery = new AQuery(ChatApplication.getInstance());
androidQuery.ajax(src, Bitmap.class, 0, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap bitmap, AjaxStatus status) {
super.callback(url, bitmap, status);
if (bitmap != null)
myBitmap = bitmap;
}
});
} catch (Exception e) {
Log.i(TAG, "Error due to " + e);
}
return myBitmap;
}
AQuery aq = new AQuery(context);
aq.ajax(url_of_image, Bitmap.class, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap object, AjaxStatus status) {
}
});
Im sorry for replying late,But this is best library I have ever came across.
Yes,You can download. Bitmap object will give you the image.
You can create multiple instances of Aquery if you want to download or pass the each URL after one download finishes,you can use any loop for that.

Volley Library return bitmap

I'm trying to use the library volley, but I'm in doubt.
The volley library has some function that simply returns a bitmap?
pseudocode:
Bitmap bmp = Volley.getImageURL (url);
Thank you
I think it has such a functionality:
http://blog.lemberg.co.uk/volley-part-3-image-loader
Sample code:
String imageUrl = "http://some.server.com/image.png";
Volley.newRequestQueue(this).add(new ImageRequest(imageUrl, new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap bitmap) {
// Do something with loaded bitmap...
}
}, 1024, 1024, null, null));
But there is better library for loading images from the Internet - Picasso
Sample code:
String imageUrl = "http://some.server.com/image.png";
// This request is synchronous, so it shouldn't be made from main thread
Bitmap bitmap = Picasso.with(this).load(imageUrl).get();

is it possible to download images from cache memory in picasso?

I was using UniversalImageDownloader for my app.in UIL we can save images from cache memory.
File cachedImage = ImageLoader.getInstance().getDiscCache().get(imageUrl);
if (cachedImage.exists())
{// code for save 2 sd
}
Is it possible in picasso?
There is a private Method in Picasso -
Bitmap quickMemoryCacheCheck(String key) {
Bitmap cached = cache.get(key);
if (cached != null) {
stats.dispatchCacheHit();
} else {
stats.dispatchCacheMiss();
}
return cached;
}
Modify the source according to your need.
You can do like this , Use OkHttp & Picasso:
public class APP extends Application{
public static OkHttpDownloader okHttpDownloader;
#Override
public void onCreate() {
super.onCreate();
Picasso.Builder b = new Picasso.Builder(this);
okHttpDownloader = new OkHttpDownloader(this);
b.downloader(okHttpDownloader);
Picasso.setSingletonInstance(b.build());
}
}
Then get the File from OkHttp local cache:
Downloader.Response res = APP.okHttpDownloader.load(Uri.parse(your image Url),0);
Log.i(TAG,"Get From DISK: " + res.isCached() );
storeImageFile(res.getInputStream());
You can get bitmap from ImangeView onSuccess() callback
Picasso.with(context).load(path).into(imageView, new Callback(){
public void onSuccess() {
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
//save bitmap to sdcard
}
public void onError() {}
}
WARNING: Saved bitmap may be different to original bitmap.
Below code snippet will first make Picasso load image from cache, if failed then download and display image in imageView
You can debug memory performance with
Picasso.with(appContext).setIndicatorsEnabled(true);
green (memory, best performance)
blue (disk, good performance)
red (network, worst performance).
//Debugging memory performance https://futurestud.io/tutorials/picasso-cache-indicators-logging-stats
//TODO remove on deployment
Picasso.with(appContext).setIndicatorsEnabled(true);
//Try to load image from cache
Picasso.with(appContext)
.load(imageUrl)
.networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.ic_launcher)
.placeholder(R.drawable.ic_launcher)
.resize(100, 100)
.error(R.drawable.ic_drawer)
.into(markerImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
// Try online if cache failed
Picasso.with(appContext)
.load(imageUrl)
.placeholder(R.drawable.ic_launcher)
.resize(100, 100)
.error(R.drawable.ic_drawer)
.into(markerImageView);
}
});

Load Btimap of Video thumbnails from sdcard

I am developing a module in which I need to show all the video from phone in form of video thumbnails. I have taken BaseAdapter to show all video thumbnails into GridView. The only problem is that I had to write the code extract thumbnail from video file to bitmap in getView() of BaseAdapter.
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(
videoValues.get(position).getFile()
.getAbsolutePath(), Thumbnails.MINI_KIND);
imageThumbnail.setImageBitmap(bmThumbnail);
bmThumbnail = null;
}
});
I want to load this Asynchronously with some image loader. I have already tried Aquery, Universal Image Loader, Picasso etc but none of them gives asynchronous image loading with memory caching, file caching, failure callback mechanism etc.
Can anyone suggest how can I achieve this efficiently? TIA.
To resolve this issue, I have made a class VideoThumbLoader. It asynchronously generated Bitmap and passes it to adapter. So that main benefit is that the whole process is being handled in background thread.
The code for class is as below:
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.v4.util.LruCache;
import android.widget.ImageView;
public class VideoThumbLoader {
private LruCache<String, Bitmap> lruCache;
#SuppressLint("NewApi")
public VideoThumbLoader() {
int maxMemory = (int) Runtime.getRuntime().maxMemory();// obtain maximum
// memory to run
int maxSize = maxMemory / 4;// get cache memory size 35
lruCache = new LruCache<String, Bitmap>(maxSize) {
#Override
protected int sizeOf(String key, Bitmap value) {
// this will be called when the cache deposited in each
return value.getByteCount();
}
};
}
public void addVideoThumbToCache(String path, Bitmap bitmap) {
if (getVideoThumbToCache(path) == null && bitmap != null) {
lruCache.put(path, bitmap);
}
}
public Bitmap getVideoThumbToCache(String path) {
return lruCache.get(path);
}
public void showThumbByAsynctack(String path, ImageView imgview) {
if (getVideoThumbToCache(path) == null) {
// asynchronous loading
new MyBobAsynctack(imgview, path).execute(path);
} else {
imgview.setImageBitmap(getVideoThumbToCache(path));
}
}
class MyBobAsynctack extends AsyncTask<String, Void, Bitmap> {
private ImageView imgView;
private String path;
public MyBobAsynctack(ImageView imageView, String path) {
this.imgView = imageView;
this.path = path;
}
#Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(params[0],
MediaStore.Video.Thumbnails.MINI_KIND);
// provide
if (getVideoThumbToCache(params[0]) == null) {
addVideoThumbToCache(path, bitmap);
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imgView.getTag().equals(path)) {// through Tag can be bound
// pictures address and
// imageView, this address
// Listview loading the image
// dislocation solution
imgView.setImageBitmap(bitmap);
}
}
}
}
And from adapter side, simply call:
private VideoThumbLoader mVideoThumbLoader = new VideoThumbLoader();
imageThumbnail.setTag(videoValues.get(position).getFile()
.getAbsolutePath());// binding imageview
imageThumbnail.setImageResource(R.drawable.videothumb); //default image
mVideoThumbLoader.showThumbByAsynctack(videoValues.get(position)
.getFile().getAbsolutePath(), imageThumbnail);
P.S: One important thing I had taken a note of was, due to asynchronous downloading of bitmap, there were few cases where thumbnails tend to mix up. So I have tagged the imageview with file path. This way I will have the exact thumbnail for the image.
Use SuziLoader
This loader will load the thumbnails for the videos which is locally stored on your filesystem in background.
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/video.mp4";
ImageView mThumbnail = (ImageView) findViewById(R.id.thumbnail);
SuziLoader loader = new SuziLoader(); //Create it for once.
loader.with(MainActivity.this) //Context
.load(path) //Video path
.into(mThumbnail) // imageview to load the thumbnail
.type("mini") // mini or micro
.show(); // to show the thumbnail
To get this dependency use the following steps
Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
compile 'com.github.sushinpv:SuziVideoThumbnailLoader:0.1.0'
}
ADD READ EXTERNAL STORAGE Permission in manifest
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Categories

Resources