I'm loading images from external URLs with Picasso. To prevent someone from hosting huge files that would hang my app I would like to set a max image file size before downloading it.
Is there a way in Picasso to limit the file size? If no, what's an alternative?
You'll have to provide your own OkHttpClient to Picasso (via its Builder) to handle that. Generally speaking you'll need to issue a request to the server to figure out the size of the image and only then decide if you want to get it or not. Check this answer for more details.
Related
Which is the fastest and best way to get image from server in android
app.
1. Image url
2. base64 format
or any other format which load image very quick as on normal internet speed.
As mentioned here base64 format is %37 larger than normal image. So if you use base64 format, you will have larger image and longer download time. In this case, you need to use normal image url.
To download images as fast as possible, you can use Picasso or Glide.
Just use glide for faster image load in your application because glide uses caching of images and it loads an image after compressing it a little bit. Even Google recommend this library to developers , Google used this library in Gmail.
I have a image uploading module in my app where user can select an image from the gallery. The problem is the size of the image can be upto 10MB. Which is very large, I want to apply some compression technique to these images before uploading them.
I did some research on the internet and found some libraries like ImageMagick, ImgMin which allows easy optimization of the images. Is there any way I can use them in my android project without the involvement of any backend server.
References:
ImgMin
https://github.com/rflynn/imgmin
ImageMagick
http://www.imagemagick.org/script/index.php
An easy option you can try is this method from the Bitmap class.
You can select the compression format of a bitmap and to optimise either the quality, or the file size. A downside is that the you need to get a Bitmap instance to start the compression, which may be something you don't want to do.
Lets consider the following, I have an app with several dozen photos I want to show the user at any given time.
Right now I'm creating multiple files for each image, sizing them for different screen sizes and storing them in their respective drawable folders.
It's increasing the size of my app dramatically.
So here is my question: Is it possible to store the images on a server and use an image library like Picasso, Fresco or something else (open to anything) to fetch that image and scale it down for the device it's running on without risking running out of memory?
I'm worried that fetching a large image, loading it into memory and then resizing it will cause the same problem as trying to display it on older devices with little memory available to them.
You can write methods to request different images sizes from your server based on client info. Just write a method to measure the screen size and then request the appropriate image based on a URL endpoint (like http://myimageserver.com/images/ldpi/image1.png).
You can do optimization post-download, such as scaling, before saving the image to a local file store.
Using a reputable image loading library is a valid method (my own favourite is Glide).
The answer to your question really depends on the number of images you want to show! If there are lots, then yes storing them on a server is probably best, but also the most time-consuming and expensive (both in time and money).
Your other (easier) option is to keep the originals in the assets folder, and use your image loader to scale and load them for you. The correct path for an image in your assets folder is file:///android_asset/your_image_here.jpg. This way, you're only keeping one version of each photo in your apk and they'll load much faster.
I have a question about mechanisms used by Picasso for downloading and caching images.
How does Picasso download an image? I know that it is using in sample size. Am I right? If image on a server is 1000x1000 but ImageView is only 400x400 then it will be download only 500x500 image and it will be cached. Or maybe it will be downloaded in full resolution and then scaled to a specific size.
Here is actual code I am - and I'm sure many more people are - using
Picasso.with(context).load(url).fit().centerCrop().into(imageView);
Picasso has no way of knowing it should download only 500*500 pixels. The fit() and centercrop() methods will make it fit even when picture is bigger than needed.
You can browse source-code of Picasso at: https://github.com/square/picasso.
Downloading images
You can see that Picasso downloads images with implementation of Downloader interface. It uses default downloader named OkHttpDownloader, which utilizes OkHttp library. When it can't be loaded, Picasso uses UrlConnectionDownloader.
Recognizing size of the images
Picasso doesn't know size of the images before download. If you are developing back-end server, you can specify size of the images in some way, so your mobile application will know it by performing a concrete request, but it can't be recognized by Picasso itself. Picasso has to download image in a full size and then this image can be cropped or resized by this library.
Cache
We can find the following information about Cache in the Picasso documentation placed in source code:
Picasso instance is automatically initialized with defaults that are
suitable to most implementations.
LRU memory cache of 15% the available application RAM
Disk cache of 2% storage space up to 50MB but no less than 5MB. (Note: this is only available on API 14+ or if you are using
a standalone library that provides a disk cache on all API levels like
OkHttp)
Three download threads for disk and network access.
It explains usage of cache in this library quite clearly.
I'm just not sure, if Picasso stores images before transformation (resizing, cropping, etc.) or after transformation in cache. First option seems more reasonable for me, because we decide to apply a different transformation later, so we may want to keep original image.
I'm making an android app, here the images are getting from Cloud, is it good idea to download images and save it & use it further. Or download images every-time user uses the app, what idea you prefer is the best?
Because downloading images always is slow & its bad i know but at some point if the images are updated then how to get to know about it?
You should definitely cache your downloaded files!
Do it in your internal app directory where only you do have access to (or otherwise external storage, thats still ok).
Bandwidth and connections are always expensive and should kept low as much as possible.
So your user can see images fast even on a bad connection and your app doesn't waste his valuable bandwidth of a users data plan.
Maybe this could also help you:
https://github.com/novoda/ImageLoader
http://www.androidhive.info/2012/07/android-loading-image-from-url-http/
Make it easy on yourself and use something like Android Smart Image View. It takes care of loading and caching, and it's just about a drop-in replacement for Android's ImageView. Universal Image Loader is another alternative, more configurable, but not as quick to implement.
I used https://github.com/nostra13/Android-Universal-Image-Loader
but I think you not want only download and cache.
these no trick ,if you want check weather the image update or not, you can add metadata for image, just like md5 .
in html and browser, you can set expires header for a image:
enter link description here
but in android app, you control all yourself.
Downloading images and saving them is probably the best way to do it because you don't want to download the same images over and over. If the images are updated you can delete the older one and download the new ones. Just make sure you don't download/save a million images. Take a look at this library. It has a built-in cache on sdcard/external sd.
Downloading images from the net for display, with possible requirement of caching is a very common problem that many people have solved, you can try these solutions to see which fits you:
Ion (https://github.com/koush/ion) - very flexible and feature complete, plus it can download more than images but JSON, Strings, Files, and Java types as well. The part that I really like about this is that it can automatically cancel operations when the calling Activity finishes, so users don't waste time & bandwidth downloading images that will no longer be displayed
Universal Image Loader (https://github.com/nostra13/Android-Universal-Image-Loader) - equally capable for most use cases but for downloading/caching images only