I'm currently using Picasso 2.0.1(also tried 1.0.2 before) and obtaining bitmaps from pictures on the web.
All is working great, I've seen improvements in loading the images ... at least it seems faster.
My question is, how can I get statistics from the activities done by PICASSO? I wanted to know if the picture was obtained from the cache or downloaded ...
I'm trying to obtain information with com.squareup.picasso.StatsSnapshot, however it doesn't seem to get updated... or I'm not using it correctly.
Picasso pi = Picasso.with(getActivity().getApplicationContext());
Bitmap bitmap = pi.load(url.toString()).get();
Log.d(this.getClass().getSimpleName(),"Cache hits:" + pi.getSnapshot().cacheHits + " Cache misses:" + pi.getSnapshot().cacheMisses);
adding a log before and / or after the load call always return the same result
Cache hits:0 Cache misses:0
What am I doing wrong or how can I obtain this information?
Thanks in advance!
Marc
To get the colored triangle that David Hewitt is describing, you actually have to use setIndicatorsEnabled like so
Picasso.with(mContext).setIndicatorsEnabled(true);
You can get stats in your logs for Picasso by using setLoggingEnabled like so
Picasso.with(mContext).setLoggingEnabled(true);
You can search the log with a "Picasso" filter and see where Picasso gets the image and how long it takes. Very handy!
According to the website here:
http://square.github.io/picasso/
You can do setDebugging(true) and it will place coloured triangles in the corner or each image that will indicate whether they were loaded from the web, the disk or memory. I can't find any specific reference to the functions you were using on the website, but this may meet your needs instead.
You can call this from the onStop() or onPause of your Activity or Fragment
StatsSnapshot picassoStats = Picasso.with(context).getSnapshot();
Log.d("Picasso stats ", picasspStats.toString());
then from the Android logcat select verbose and filter by Picasso.
You will get a log something like the following:
Picasso stats: [main] StatsSnapshot{maxSize=76695844, size=75737296, cacheHits=656, cacheMisses=1091, downloadCount=8, totalDownloadSize=213376, averageDownloadSize=26672, totalOriginalBitmapSize=437547196, totalTransformedBitmapSize=609434304, averageOriginalBitmapSize=527801, averageTransformedBitmapSize=735143, originalBitmapCount=829, transformedBitmapCount=826, timeStamp=1484426664382}
'get()' is synchronous and skips the cache. Use one of the 'load()' methods to harness Picasso's full powers.
Related
Have you ever been going through apps like 9gag, Instagram or Facebook? You notice, that while scrolling the pictures load into the recviewer. They sort of come in one by one while you can still use the app.
I have implemented my own custom recviewer and am stuck right here:
pictures = KumulosHelper.Pictures.getNewestXPhotosFromUserInRange
(strUsername, "6", startNumberOfTask.ToString(), "1");
foreach (var picture in pictures)
{
startNumberOfTask++;
var metrics = Resources.DisplayMetrics;
lstData.Add(new DataForProfile()
{
imageId = startNumberOfTask,
img = (Bitmap.CreateScaledBitmap
(KumulosGeneral.DecodePhotoFromBase64(picture.photo),
metrics.WidthPixels, metrics.WidthPixels, true)),
description = picture.taskId.ToString()
});
}
Where I type in "6" is where I get 6 pictures to load into my recycle viewer form the server. I can type in 10 or 20 and it continues loading those pictures. So, I could probably set up a "reachedbottomevent" to continue loading new pictures when the viewer reached the end. But that would mean that the user has to wait everytime he or she reached the bottom of the matrix. This is pretty annoying. Also, the whole activity wont start untill all pictures are fully loaded.
How do I get my recview to behave like the afforementioned apps above? Some sort of "smart" loading the pictures?
Thank you for the input!
Try using the Picasso library which is very reliable and easy to use. It also loads pictures in a background thread.
https://www.nuget.org/packages/Square.Picasso/
Also, the whole activity won't start until all pictures are fully loaded.
In order not to block your UI thread try using a BackgroundWorker or a Task.
At last, if you want to load a new batch of images before the user reaches the bottom of your list, then change your logic to trigger the call for a new batch for example when the user scrolls half the table.
Using Tensorflow 1.0.1 it's fine to read optimized graph and quantized graph in android using TensorFlowImageClassifier.create method, such as:
classifier = TensorFlowImageClassifier.create(
c.getAssets(),
MODEL_FILE,
LABEL_FILE,
IMAGE_SIZE,
IMAGE_MEAN,
IMAGE_STD,
INPUT_NAME,
OUTPUT_NAME);
But according to the Peter Warden's Blog(https://petewarden.com/2016/09/27/tensorflow-for-mobile-poets/), it's recommended to use memory mapped graph in mobile to avoid memory related crashes.
I built memmapped graph using
bazel-bin/tensorflow/contrib/util/convert_graphdef_memmapped_format \
--in_graph=/tf_files/rounded_graph.pb \
--out_graph=/tf_files/mmapped_graph.pb
and it created fine, but when I tried to load the file with TensorFlowImageClassifier.create(...) it says the file is not valid graph file.
In iOS, it's ok to load the file with
LoadMemoryMappedModel(
model_file_name, model_file_type, &tf_session, &tf_memmapped_env);
for it has a method for read memory mapped graph.
So, I guess there's a similar function in android, but I couldn't find it.
Could someone guide me how to load memory mapped graph in android ?
Since the file from the memmapped tool is no longer a standard GraphDef protobuf, you need to make some changes to the loading code. You can see an example of this in the iOS Camera demo app, the LoadMemoryMappedModel() function:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/ios_examples/camera/tensorflow_utils.mm#L159
The same code (with the Objective C calls for getting the filenames substituted) can be used on other platforms too. Because we’re using memory mapping, we need to start by creating a special TensorFlow environment object that’s set up with the file we’ll be using:
std::unique_ptr<tensorflow::MemmappedEnv> memmapped_env;
memmapped_env->reset(
new tensorflow::MemmappedEnv(tensorflow::Env::Default()));
tensorflow::Status mmap_status =
(memmapped_env->get())->InitializeFromFile(file_path);
You then need to pass in this environment to subsequent calls, like this one for loading the graph.
tensorflow::GraphDef tensorflow_graph;
tensorflow::Status load_graph_status = ReadBinaryProto(
memmapped_env->get(),
tensorflow::MemmappedFileSystem::kMemmappedPackageDefaultGraphDef,
&tensorflow_graph);
You also need to create the session with a pointer to the environment you’ve created:
tensorflow::SessionOptions options;
options.config.mutable_graph_options()
->mutable_optimizer_options()
->set_opt_level(::tensorflow::OptimizerOptions::L0);
options.env = memmapped_env->get();
tensorflow::Session* session_pointer = nullptr;
tensorflow::Status session_status =
tensorflow::NewSession(options, &session_pointer);
One thing to notice here is that we’re also disabling automatic optimizations, since in some cases these will fold constant sub-trees, and so create copies of tensor values that we don’t want and use up more RAM. This setup also means it's hard to use a model stored as an APK asset in Android, since those are compressed and don't have normal filenames. Instead you'll need to copy your file out of an APK onto a normal filesytem location.
Once you’ve gone through these steps, you can use the session and graph as normal, and you should see a reduction in loading time and memory usage.
I am experiencing a strange bug in PhoneGap on Android 4.4, for which I couldn't find any solution online. In my app, I am loading a lot of different images from a remote server, and as the user navigates back and forth, new images are loaded on each page (4 at a time, to be specific, through jQuery-generated html). After having navigated back and forth for a little while, some images will randomly not show up and instead show the typical "broken image" icon.
Now, here comes the strange part: I have been following the instructions at jQuery/JavaScript to replace broken images and done a few tests of my own. In conclusion, the naturalWidth and naturalHeight parameters report the right sizes of the images, and complete reports true for all images. Therefore, the solutions mentioned in the above SO thread don't work at all. Changing the image src doesn't help, either with or without a setTimeout (I tried adding the current timestamp as a parameter to the image path as well).
Did anyone else encounter this issue at all, or am I going crazy here? :)
EDIT: By the way, no error is ever reported. Therefore, no error handler is called when loading the image, making it useless to solve the problem with the already suggested methods (see the link above).
This is how i handle error images,
<img src="images/imageName.jpg" onError="onErrorFunc(this);" alt=" " />
function onErrorFunc(elem){
var imgUrl = "https://alternative-image";
elem.onerror = function (){
elem.src='images/noimage.jpg';
}
elem.src=imgUrl;
}
Hope it helps!
I have a ListView extending ArrayAdapter. I am using a view holder patter for the getView and here is a part of my getView method which loads images using picasso. The following code is expected to load images into my image view inside every list item.
Picasso.with(mContext).load(imageURL).fit().into(holder.myImageView,
new Callback(){
#Override
public void onError() {
holder.myImageView.setVisibility(View.INVISIBLE);}
#Override
public void onSuccess() {}});
So here is the problem: this works fine for OS < Android 5.0, but in the case of Android 5.0 (Lollipop), it looks like Picasso is fetching these images when my app is installed and run for the very first time, but when I launch the app again, the images don't load. Not at all sure what the problem is. I am not loading huge images, you can assume all the images that I am loading are only of the size of a small icon/thumbnail (around 120X120). I am using Picasso 2.4.0 for my application and the phone that I am using for testing is the Nexus 4.
Open Issue as of this edit: https://github.com/square/picasso/issues/633
Alternative:
I struggled to find an answer for very long time yesterday night. I explored Picasso really intimately trying several stuff. None did work. So right now what I am doing is:
if(api>=21) //Keeping in mind about any updates beyond 21
Use Android-Universal-Image-Loader
else
Use Picasso
For more information on Andorid Universal Image Loader.
Please visit https://github.com/nostra13/Android-Universal-Image-Loader
Its awesome with its cusotmization.
Agian, dont get me wrong, I am 100% +ve there is a solution with Picasso, I am sure I will find it someday, I will post it here then, but for anyone who have problems like me, I think the above is the way to go. Please suggest if you have anuy other better way.
************************ ISSUE FIXED **************************
https://github.com/square/picasso/issues/632
https://github.com/square/picasso/pull/860
************************** ISSUE FIXED ****************************
I am trying to make an App that acts as a map of a local area. Because of the local area, I do not want to use Googlemaps or its API. I want to use a .png that I import. My image is 2300 x 1650 and after searching for a way to load this image into my Activity (because just making one bitmap throws OOM exception), I found a way using Drawables. My code to implement the drawable is...
InputStream mapInput = resources.openRawResource(R.drawable.mymap);
mapDrawable = Drawable.createFromStream(mapInput, "mymap");
mapDrawable.setFilterBitmap(true);
mapDrawable.setBounds(0, 0, MAP_WIDTH, MAP_HEIGHT);
myCustomView.setMapDrawable(mapDrawable, MAP_WIDTH, MAP_HEIGHT);
and this works all fine and dandy and allows the App to function. However if I BACK or HOME screen out of the application and attempt to reload it, I get a NullPointerException when I try to access mapDrawable (so in this line of code, on mapDrawable.setFilterBitmap(true))
After my app fails, if I try to reopen it again, it works again. Unless I BACK or HOME out of it and then it fails. It always fails on the attempt to reopen.
I don't understand what I am doing wrong.
Here is a sample project showing asynchronous in google Maps..
https://github.com/commonsguy/cw-advandroid/tree/master/Maps/NooYawkAsync/
Try this if it works..