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.
Related
I have a mobile app which has a screen with list of small images (3x3 grid). Click on image takes user to detail screen, where user can see that image in original size. Now, problem is that, for now, on backend side i only store full sized images (which i know is bad), but when i retrieve images for list i would like to return thumbs for original sized images.
The question is - what is the recommended thumbnail size to return?
Consider that this is an iOS and Android app.
Thanks in advance!
It depends how big you want to show it to the user.
i personally prefer 256X256
I'm taking whole screenshot of a WebView and display the bitmap on an ImageView. The bitmap can be 7 screen height. (E.g. 1440x14000 px)
I'm frequently face with
OutOfMemoryError.
I've seen this
This says that load a scaled down version into memory but I don't want to lose image quality. There are the same approaches on the web.
Is there any way to handle OutOfMemoryError without loading scaled down version?
The bitmap can be 7 screen height. (E.g. 1440x14000 px)
Note that this means that the user cannot see the whole image at once at full resolution.
I'm frequently face with OutOfMemoryError
On most devices, you will have a very difficult time loading an image that large, as you cannot get a single contiguous memory block that big.
This says that load a scaled down version into memory but I don't want to lose image quality
To some extent, you do not have much of a choice. If you want the user to see the full extent of the picture at once, the image has to be scaled to fit the screen.
Is there any way to handle OutOfMemoryError without loading scaled down version?
There are ImageView replacements that offer pan and zoom. Some of those, such as this one, handle loading in pieces of the image at a time, with whatever scaling is necessary for the current zoom level, to make it more likely that you will be able to show the user the entire image.
It is not a solution, of course, but I'm also not familiar with your exact needs, so maybe this may help you a little - you can try to play with bitmap options during decoding. Try to use Bitmap.Config.inPreferredConfig as RGB_565 - this will reduce size of your bitmap twice comparing to default ARGB_8888. But, of course, if you use complex images in your web page this may reduce their quality.
Before to say this is a duplicate, please read as I did not find my answer on the other topics. I am trying to resize (if needed) a bitmap to a specific size but this size is in Ko (not height/width).
The problem is the following
1) In my app, the user can select pictures from facebook, gallery or the camera
2) I get all of those as bitmap format and they all came with different width to height ratio and different compression rate.
3) I need to store those pictures on my server so that the user can see them in my app at a later point if he comes back. But I want to save a version of about 200/100Ko for each picture.
4) The problem is that if I resize the bitmap to be the same size say 800*600, and then compress the picture to 50% then some bitmaps (that were compressed) will basically take more space than if I was doing nothing and they will not look as good too as 2 layer of compression will be done.
5) I need to find a way to compress my bitmap only if it needs to be compressed and not increasing his size by doing those manipulations. The documentation on this topic looks much more limited, as every questions asked about resizing a picture to a certain size in width/height but not in terms of space.
If any one has links or recommendations on this, would be very happy to hear from you, thanks
I am writing a Android app which need to display some high quality picture(took from professional DSLR). The problem is it can't be display from gallery.
I choose a photo in Gallery first. The target picture is 2464*1632 JPEG, roughly 4.5M;
Then I just need to compress it to 800*600 and display it in imageview:
image.setImageBitmap(this.bmp);
Thing is that I have tested other image I downloaded form internet(really low quality), and it works without any problem. Can anybody tell me why it can't be displayed? I will be really appericiated
Large images are tricky to handle due to limited memory. You have several choices:
Use a WebView (this allows you to have pinch and zoom functionality to make use of those extra pixels
Decode the image down to the size of the display and then put it in an ImageView using BitmapOpts http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html and changing inSampleSize. It seems you may be having difficulty with that, so consider using createScaledBitmap which just needs the dest width and height.
I'm posting images ot wall. Tried 200x200. Result on wall is: 96x96.
But I saw images on other posts with bigger dimmensions.
Where are the limitations described?
Images with dimensions bigger than 96x96 in feed is photos that was uploaded by user, and not posts created by application.
Documentation is a bit poor on that but there is no hard limit for image dimensions but the image will be displayed in different sizes across different views (this was stated in comments to several bugs, and I cannot find the source right now).
This means that in feed image will be displayed one size and the Timeline may display bigger version if available, and some other views may use other dimensions as well. One rule exists (which is stated about images across different documentation pages: Share, OpenGraph Protocol, Feed Dialog)
The image must be at least 50px by 50px and have a maximum aspect ratio of 3:1
When you share a URL, the maximal size for a linked image is 90x90.