I have a image (resolution 8328x3987). And I want to load that image in my app with zoom controls for better viewing.
As we all know that Android will not load large images directly on device (like in my example). So Android system suggested us to scale down the image to load large images. I have tried this and scale my image upto four times as:
options.inSampleSize = 4;
Using this way my image will displayed on screen, but when I zoom-in the image then this image becomes unreadable (text becomes very blurry), this is because, maybe I scale down the image before showing?
But when I see that image in to device's default gallery app (Android Lollipop, Photos app), then this image looks like a mapview (only visible portion is readable and outside is blurry, and when I move the image then visible area becomes readable) when I zoomed in at max level. So my questions is:
Is Android lollipop added any new way to load large files that looks like mapview?
If not, then do you have an idea how that apps do this or any example?
Reducing the sample size of an image that big will not work at all.(very very bad resolution and memory consumption)
I suggest you to divide image to tiles and recycle the views just like map views do.
This library may help you. Or you can do it your way too.
I want to have the posting-a-photo usecase in my android app.
This is the scenario I have implemented:
1. User posts a photo.
2. On the client side I scale the photo* , compress it and send
it to the server.
3. I store the photo on the server.
4. Users, who can view the photo, fetch the photo from the server.
The problem with this approach is that it doesn't take into consideration
the different-screen-sizes problem.
Let's say user A posts a photo.
User B, which has a phone with a larger screen**, fetches the photo
from the server. The photo doesn't fit good in the environment
since it has fixed width and height determined by user A (scaling in step 2).
I cannot simply scale the photo and put it into user B's ImageView, because
I am risking to loose the aspect ratio of the photo.
One approach that comes to mind is to simply remove the step 2 from the scenario.
I send the photo to the server, and when a user tries to fetch it
I scale the image according to the user's screen size (which I receive as parameters in the fetch request).
The problem with this approach is that, on each request, I will have
to scale the photo on-the-fly and send it to the client.
Another problem is the efficiency of uploading a photo, because I don't scale the photo (before uploading it).
It takes much more time to upload a full 2MB (or even a 500KB) photo than to simply upload a scaled photo (~20KB).
What are my options?
Since I am relatively new to Android, chances are that I am missing something essential.
Cheers!
*I scale maintaining the aspect ratio.
** Sorry for the terminology, i don't know how and when to use high density/pixels correctly. :-)
I have own dedicated server with unlimited traffic and 4T HDD. So, basically what I do is:
User take a picture by phone
User upload image to the webserver
Using ImageMagick + mozjpeg 3 I resize image 3 times and save it with prefixes small_, medium_, large_ OR with prefixes pre size: 1024_, 640_...
Now, my app can find user's screen dimensions and load image by doing request for specified prefix.
My arguments for doing in this war are:
Free traffic
Big HDD
Fast user's internet speed
When upload in another thread, and show to user another activity, he doesn't feel the "long waiting time" for uploading large images.
You always can resize photo on device, from 10Mb to 2Mb, for example, and on server do other resizes.
Now about image ratio. There you cannot to do a lot. You must decide, what to do in case that user with large screen and own aspect ratio tries to load image that was uploaded by user with small screen and own aspect ratio.
The truth is that screen size doesn't matter. What is matter is a ratio. So, you can load image, put it in ImageView, and this will filled with black background if the image is "smaller". O r you can load large size of image, crop it and put it to the ImageView. Larger image is used only for better quality.
In my case, I always do crop images if I use it as preview. I think it's looks more beautiful. When user want to view full size image, I download full image and show it as is.
A good server that handles images should:
receive images at high-quality
save or cache the images in multiple sizes (small, medium, large)
serve images according to a size parameter (larger phones ask for the large image)
There are many solutions for this kind of server. Most of them resize the image on-the-fly and cache the result. The client tells the server what size it wants. One example is the image handling in Google Play. Go to the play webside and view the urls of the app-icons (example). They have a width parameter.
You can also think of a maximum dimension (like 2048px) and resize the image before upload only if needed.
The client that views the image needs to decide on what size it asks from the server or it can resize the image on the phone, instead of relying on the server. Do this if traffic is not an issue. Consider using Picasso or Glide to make things easier.
Regarding aspect ratio: The client that views the image should handle this. It should expect any aspect ratio and be prepared for it. Use android:scaleType on the ImageView and decide which scale type fits your scenario. Here are the scale types. If you don't want black lines and want to occupy as much as possible from the screen, use CENTER_CROP - but you might end up losing parts of the image.
In most apps the original aspect ratio in maintained and two black "stripes" are added if your screen doesn't match.
I think it's not possible to manage all screen ratios...
ImageView has android:scaleType attr that preserves aspect ration to be broken,
like fitCenter or centerInside
And also calculate size of fetched image and set view size by yourself.
I have an image that is to be displayed in about four different sizes depending on which activity the user is viewing. For instance a ListView will show one size, a GridView will show one size, a slide show will show one size, etc. If I use Picasso, will it download the image once or will it download one image for each size? Of course, I am taking into account that Picasso caches images (which is what I want). The key point here is that I have a single url for the image since it is one image.
Note that to keep the example simple, I mention one image. But of course I am talking about a set of images each of which needs to be manipulated as mentioned in the paragraph above.
If I use Picasso, will it download the image once or will it download
one image for each size?
Once for the original size as you get from the URL.
You can use the resize() method to resize the image and the original image would still stay at full resolution. I have done that in my app where I displayed a 600x600 image at 150x150 in a thumbnail and in full resolution later.
I have multiple large images and I would like to use these in such a way that it would allow users to do continuous panning. I couldn't stitch all the images into one image as it would give memory limit error. Also I want to compress the images. I believe one option is to place the images in a virtual grid shape and show image based on current viewport & touch position (it might have some issues when switching between images). I was wondering if there is any other easy ways to solve this.
You can split the images into smaller ones and load only the images currently visible on the screen and probably the next one to provide smoothness while panning. So if you have 6000x4000 you may want to automatically split them into 24 images 1000x1000.
My scenario:
In my activity, I have to show 2 galleries, 1 with large image and another is a thumbnail(same exactly like default Gallery application).
My doubts:
I am planning to save as 2 images(1 with large size and another one with thumbnail size) in sdcard for fast processing. Is that good practice? since it will increase the size.
Or Shall I resize the large image during the getView method of BaseAdapter to small size for displaying in thumbnail gallery?
Which one is the good practice? I don't want to slow down my app.
See this example.
I will suggest you that, put only your large image inside your sdcard. But at runtime, Android provides a good facility to get Thumbnails using MediaStore.Images.Thumbnails.
Edit:
You can also get use Loading Sample Sized Bitmap. This will first create a sample size of your requirement. Then will give you a Thumbnail sized Bitmap.
StackOverflowAnswers:
1) Get thumbnail of image on SD card