I want to make an Android application that has the same look as Instagram, which means every profile has a gallery of photos.
My question is about storing and retrieve those photos. I want to know what is the best practice for photo storage in a database (MySQL), more precisely:
Should I store photos with original size (2mb for example) or resize them with smaller size?
Should I store them with two version (smaller size photo, and normal size photo)?
Saving images in the database looks like overkill, it's not needed. Saving on disk should be fine.
Although you should focus on your business logic & leave this to image libraries which does this stuff & do best for memory & performance.
Some famous libs are:
Picasso
Glide
Universal image loader
Fresco
& you will find many more
Almost each library does lots of stuff for you, such as:
In memory cache(LRU Cache) - so that UI thread is not blocked from doing I/O
operation from disks
Disk Cache - To keep images saved for further
app sessions, also when memory cache reaches its limit its have to be
evicted from it., you can specify disk cache size.
Various image scaling strategies
Image transformations
Clearing up bitmaps for freeing up memory
Network operations on background threads
Background threads management & so on..
My suggestion is to go with one of the image library
I dont think the best practice is to store the photos in a database.
In the DB you store the link/location of the photos example a url to a photo.
About smaller size photo it depends on what you are trying to accomplish because now you need more space to pay for and maybe less bandwidth because you can put thumbnails and let it only load the original size when a user clicks on it. So it all depends what and how you want to archieve
Best practice for storing images is to simply cache them as files and not save them in a database. You could save them as blobs in an sql db but they should be less than 32px by 32px to make things smooth. Everything else should be saved as files. Let me give you an example of WhatsApp.
WhatApp caches most of it's images as files and only saves the pixelated thumbnail in a database.
Related
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'm trying to create a CRUD android application.
Now, when the List Activity is shown, it will display the items created along with a thumbnail of the original image.
What is the best practice for displaying a thumbnail in an Android application with Volley? Should I generate a thumbnail for the images uploaded or just re-size the image at the client side?
It's hard to come up with a general answer for this questions because it all depends on how many images you're trying to download and how important showing the thumbnails is.
I would personally generate the thumbnails on the server side as soon as they are uploaded by the user. Doing this has several advantages:
All your app has to do is request the thumbnail and render it, which is much simpler and less CPU-intensive than using Volley's ImageRequest.
Smaller images means less data usage. You definitely don't want your app to download a 10MB 25-megapixel image over a 3G connection just to shrink it to a 100x100 thumbnail that the user might not even care about.
The only drawback that I can think of is that you might have to generate multiple thumbnails, one for each screen size (e.g. one for hdpi screens and another for xxhdpi). This is slightly more expensive on the server side but might make your UI look much better.
Also, remember to cache thumbnails in your app's cache directory so you don't have to re-request them every single time you want to show them.
Is there a general guideline or rule of thumb on when I should cache a photo?
For example I have a grid view of smaller icon images. This page isn't at the beginning of the app so there's no guarantee a user sees it, these images could change server-side but for the most part they won't. Should I cache them because there are so many or not worry about them because they are small?
Another example would be if I click on one of the images mentioned above it will lead me to a view with one larger image, should I cache this image since it's larger or should I let the user make a network request each time?
I'm not looking for an answer for these specific questions, but rather a guideline to follow.
To clarify by caching I mean saving the file to storage. Also, is there a better method than this?
Thanks for the help!
Caching is an important feature in user experience, so even if there's no guarantee the user sees that particular 'page', it a nice thing to have.
Saving images in a cache depends directly on many variables:
- How much time does it take to regenerate images if not cached
- How many images are we talking about
- How often do they change
- What size is each image
For example, having 100 thumbnails of images that change every month makes a lot of sense. Caching 200 images with 1024x768 resolution that change very often doesn't.... or does it? The answer is very variable.
Also cache should always have storage boundaries. Even in the previous example with the large images, you could limit the cache to a a certain storage capacity.
Normally the cache saves a local copy of the most recently used items. But you can implement a more sophisticated algorithm, for example, saving the most visited images instead of caching the most recently used.
The app I am making takes videos and pictures and displays them in a gridview. My hope is that the user will use my app frequently and take a very large quantity of videos and pictures. The problem I'm trying to figure out what route to take when storing the bitmap thumbnails. I'm currently using a SQlite database to store all the bytes and then querying them and creating a bitmap to be displayed. Even if I'm doing this in a background thread, this seems really inefficient especially as the database grows and there is more data to query through.
I feel using a memory cache would allow for faster retrieval and a better user interface. However, I'm afraid that if the user creates a lot of thumbnails then I run the risk of running out of memory.
My main questions are:
Is storing a bunch of thumbnails even something to be concerned about when caching?
Are there any advantages of using a SQlite database in this situation?
Thanks
You shouldn't store the images as bytes, you should store the images as files in the cache folder and in you db you should only store the paths towards the images (or the name of the images if you know the folder). You should cache the thumbnails also, it will increase the speed when he looks through the list of thumbnails (resizing an image takes some time).
P.S. You can use some 3rd part libraries for this.
im wondering if storing images as BLOB in the sqlite database would be a good idea?
Does anybody has performance - experience with storing images (blob).
My android app would be a small one, which will need to handle 20 to 100 images (100 kb up to 1MB per image). Worst case: I would say, that my database could reach a size of 100 MB. Does this has significant impact on the database performance?
Average case: I guess the average user of my app has 40 images with 200 kb per image, so the size of database would be around 8 MB.
Btw. of course the database stores also other "normal" data, so its not a image database only :)
Is storing the path to the image which is stored on the storage(internal or sd card) a better approach? I guess that retrieving the image file path from the database and open and load the image from file would be a little bit slower (but not really significant, since I need to load only two images at once).
A second question:
If I would use the second approach (store the path to image file in the database and load the image file):
Does a disk cache (DiskLruCache) is something useful in this scenario? Would it bring a significant performance boost? My understanding is that a Disk cache would store bitmaps (instead of encoded jpg or png) and therefore a disc cache would load a bitmap directly from storeage and my app would save the time to decode the image(jpg or png). Is that correct?
Btw. In the "database approach" i would store the image already decoded as bitmap. So it seems to me to be something similar as the disc cache, isnt it?
Edit:
I forgot to tell you, that i need to store the images persistent on the device. Im not talking about caching images that for example I have retrieved from a web service ...
My guess will be that the database will get significantly slower if you store that much of information in it, especially when you retrieve the images themselves.
On the other hand, as I get it, every user has the images associated with him downloaded after the application is installed. This is perfect place for using a library another SO user recommended to me in a question of mine I asked couple of days ago: Universal Image Downloader. Here is a link to the thread I speak about.
This library uses on disk caching, but abstracts away all the complexities for you (hopefully, I have not yet tried it, but it seems promising).