The the iOS Mail app used to have a handy feature (I believe they removed it with the advent of Mail Drop) that would give you the option to select a scaled version of an image attachment. The great thing about this feature was that it would actually calculate the file size of each of the scaled images; shown below:
The server I am uploading images to has a small file size limit (10 MB), and I would like to emulate this functionality in order to prevent uploads that exceed this limit.
With the assumption that the image is not actually scaled down three times in order to determine the file size of each of the scaled images; how would I go about doing this?
I have not been able to find any information regarding some type of formula to calculate the file size of a scaled down image based on the size of the original image.
Given the delay i've always seen when I pop that dialog on older devices, which is a non-trivial delay, I challenge your assumption that Apple isn't just doing the dirty-deed here -- ie. writing those JPGs directly to memory/disk and reading the size, rather than calculating this... ie. let data = UIImageJPEGRepresentation(image, 0.6)!
The trick is likely that people are falling down the "it needs to be at least 80% quality to be real!" hole. That's only true if you have a terrible JPG/media library. In reality, if you're writing a reasonably complex UIImage to memory/disk and you don't need transparency, then 60% is plenty.
Related
Apologies in advance for such a basic question, but this is my first app and I can't quite find a clear answer for my situation. All the images in my app are stored in the drawable folder, I'm NOT downloading any images from the internet. All the information I come across when it comes to multiple image sizes seems to refer to the occasion when the app is fetching images from the internet.
So currently most the images in my app are one size, customized for the largest size - xxxhdpi. However, I understand the app is doing some work to "shrink down" those images for the xxhdpi size screens.
I'm having second thoughts about this one size fits all approach. I'm thinking that perhaps the app doing the work to shrink the image down might take up extra memory and negatively impact performance. I've been looking at the Android Studio Profiler and I've been trying to understand the Graphics Process when I look at the Memory Graph.
More generally speaking, is there a benefit to having the smallest size images possible, even for the xxxhdpi? For example, does it hurt (memory wise or in some other aspect) to use a .png image when I could use a lower quality jpg? Again, just to super clear, this is just in the scenario when the app has all of its images in the drawable folder. My app has options where players can change the game background and other images so I want to be sure I'm optimizing how the images for best performance. Thanks.
Memory. If you load a bitmap of x by y pixels, in memory that takes 4*x*y bytes. For a full screen image, you can expext that to be 4000*1000*4 or 16 MB. That's a good chunk of memory to a small device, which also tends to have less RAM. If instead it needed one at half the resolution, you would have 2000*500*4, or 4 MB.
Obviously this scales with size. The smaller your images, the less memory wasted. I wouldn't argue that you need to provide every size, but if you're using large images I'd provide more than one. Also, for anything that isn't incredibly complex (like icons) I'd consider vector images instead (although that's a CPU time vs memory tradeoff).
You mentioned png vs jpg. There's two things to consider there: apk size and image quality. JPG is smaller, so it will lead to a smaller apk size. PNG is lossless, so it will have higher quality (although whether that matters requires a human visual check- it matters less than you'd think on a lot of things). Interestingly it doesn't effect the amount of memory used at runtime, because both are held in the Bitmap object uncompressed.
Does android want that we put different version of an image (for different dpi) to avoid resizing-artifact because their scaling algorithm is not quality-efficient (to be fast i think) ?
But anyway, it's obvious that android will scale all image just for maybe some pixels, so, resizing-artifact does ONLY appear when we do a big resizing ?
Through this questions , i want to understand the utility of putting different size of image and why we don't just put a big resolution image and let android scale down every time.
(I have also a suppositon that i want to confirm, maybe the algorithm take more time when the scale factor is important)
Thx.
If you put the highest quality images in your app, your app consumes more memory (RAM) and if the device has less memory than your app freezes more frequently. This will not provide a good user experience as we all want that our app should be smooth in performance.
Besides all, I had also tested that if we put larger images and try to display them, Sometimes the app also crashed by giving an error of out of memory.
If you want to only place one image in your app to reduce the size of your app than I advise you to do it with .svg images. These images are scalable and the CPU does not have to do extra processing to display them.
I hope it will help you. Thank You
Im having some memory issues with my app. It can pick an image from the users personal gallery and store it in a file to be rendered on the screen. The issue is that the limitation on the imagesize is very small. Which I have discovered lead to pretty much every image on my device being to large to handle. So the method itself became useless since it can't handle moderate sized images. I'm experiencing this only on ios devices so far.
Is there a solution? Can I compress/minimize the size of the image to a smaller one in any way? Cutting all images to the same resolution? (Like Instagram's system).
If you want to reduce the image size in bytes, there are at least 3 areas you can work on:
Reduce image dimensions (pixel resolution). This almost always
causes loss of quality, but if your users are viewing on small
screen devices, and you don't resize too much, the loss won't be
significant. You can also use interpolation to minimize the visual
degradation when resizing.
Reduce bit depth (color resolution).If the image is full color (32
or 24 bits per pixel), you can sometimes get away with reducing it
to a lower color count such as making it 8-bit. Again this will
cause quality loss, but you can use dithering to reduce it.
Use better compression. Most images are
already compressed these days, but in some cases you can re-compress
an image to make the file smaller. One example is JPEG which
supports different quality factors. There are also different
sub-types (color sampling frequencies) in JPEG. So if you save an
image as 4:1:1 instead of 4:4:4, it will contain less color content
and become smaller in byte size, but the difference is usually not
noticeable to the human eye. This post has details on changing
JPEG Quality factor on iOS.
I am building a mobile application that will target iPhone/iPad and Android phones. The application will involve users taking photos and uploading to my server and later on the users will be able to look at those photos on their mobile devices (although not necessarily their own photos so an Android user might be looking at a photo taken with an iPhone).
Which sizes should I save the photos to be able to cover the most use cases? iPads are 1.333 W/H, most mobile phones are 1.5 or 1.333 W/H with some rare 1.666 W/H. Specifically:
iPad: 1024x768, iPad3: 2048x1536, iPhone and some other phones: 960x640, 480x320, 800x480.
To be able to keep it manageable, I need to decide on a few certain image sizes and save the photos in those sizes. I am not really looking for help on the technical side. I can do image scaling on the server side etc. I am looking for recommendations / best practices / lessons learned about image sizes before I go too far into building it.
Which sizes should I save the photos in to cover the most use cases?
Do you recommend any client side scaling before uploading to server to save on transfer time (for example scaling down 2048x1536 iPad photos) or should I always transfer originals?
How should I handle incompatible image sizes (showing a picture taken with an iPad on an Android device for example)? Should I pre-cut those images on my server before sending to client or should I let the client phone handle image resizing?
There is also the issue of UI. There will be other things on the page other than the photo maybe a button or two for navigation. Should I go for something smaller than the full screen size while keeping the same aspect ratio when saving pictures?
I know some of these questions don't have one answer and the answers are relative but I wanted to get some opinions. Thanks.
For Android, I think the best place for you to start would be here, it has a lot of information including standard screen sizes and how to display images while keeping them in the best possible quality.
http://developer.android.com/guide/practices/screens_support.html
I'd also suggest doing as much image manipulation as possible on your server. Images are a pain to work with on Android due to memory constraints and fragmentation. Two phones may store pictures taken the same way with different orientations, and there is no simple way to handle rotations, though it can be done (thankfully, I've yet to encounter a phone that incorrectly records Exif data, but I wouldn't be surprised if they existed...). The more you rely on the phone to do, the more chances you have for error due to manufacturers putting wrappers around and otherwise customizing how it handles media.
As for how to display, ideally if your back end is already doing a bunch of different resizes, you can include your screen density when you request the images and send the best size based on the dev guide. If you want to keep differences to a minimum, at least support med or high density for phones, and extra high density for tablets.
Just my two cents, I'm sure you'll have a lot of opinions. Good luck.
I don't have a full answer for you, but I do have some thoughts...
1) I'd suggest reducing the image sizes before uploading. If I were using your application and I had to upload a 4 meg photo, everytime I wanted to use your application, I'd probably pass. And as we venture forward, we're hitting much better technology in terms of camera phones; Nokia has released a 41 megapixel camera, which I'm guessing will create rather large images. Users having to download a 4-6 MB image is also not a great idea. Just some thoughts from a user point of view.
2) I wouldn't cut the images. You don't necessarily know what parts of the image aren't important, so how would you know where to crop it? Let the phone size the pictures accordingly and rely on the ability to zoom into pictures to see things at a larger size.
3) You could try to make a UI that hides buttons. If you have something really simple (like just going forward or backwards) you could rely on gesture controls (swiping) to move around your application. You can implement sliding drawers and menus that take up space temporarily, when in use, but give you the space back when you want to look at the main content (pictures, in your case). I've typically found that hiding buttons doesn't work well and people seem to want/search for buttons that let them navigate, but the Android gallery works just fine with menu + swiping only, so who really knows.
I am building Javascript application for mobile browsers (not wrapped-as-native app).
I noticed that Android (tested 2.3 emulator and Galaxy S device) reduces the quality of loaded images if the image dimensions exceed certain threshold (width above 1400 px or so). This make it impossible to load big bitmap images (2000 x 2000 px) without the quality going unusable.
I tested this by
Loading one big image and drawing it on the - I got pixel garbage out. If I draw grid lines using lineTo() on they have perfect quality, so the bad must be in the image pixel data
Slicing the big image to 100 x 100 slices and drawing them to a canvas - this is the only method I found resulting no quality reduction. However, slicing is cumbersome, adds extra step to preprocess images and page loading times suffers
I tested tring to load image with new Image() object, tag and CSS background: everything suffers from the reduced quality, so I suspect the probelm is the image loader itself
I also tried everything with CSS image-rendering https://developer.mozilla.org/En/CSS/Image-rendering - no luck
Viewport tag seems to have no effect to the image loading - the data is already garbage when you try to touch the loaded pixel data. I tried all possible values suggested in Android's SDK documentation http://developer.android.com/reference/android/webkit/WebView.html
Tested also Firefox mobile, desktop browsers, iOS: everything is good there.
So, what is going on - Android WebView simply can't load big images?
(smiley of hung Android robot here)
Android unconditionally resamples images and reduces quality if a certain threshold of memory usage is exceeded.
https://android.googlesource.com/platform/external/webkit/+/android-3.2.4_r1/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
There is no way to access the original image data in intact.
I posted a question regarding this to android-developers Google Group and kindly asking to maybe provide some kind of flag to opt-out from this behavior.
Meanwhile, if you are considering developing HTML5 web apps and you might use big images, you simply need to preprocess them on the server-side by slicing, send in smaller images to the device and then reconstuct the original image using or putting many tags inside a container element.
Another option would be load image "manually" by writing a PNG decoder which directly loads the image to , bypassing ImageSourceAndroid class.
The question is old so probably few things changed, but if you are having image quality issues with WebView then consider converting your image into PNG format.
Somehow when I load the jpeg version of the image the quality is low, while loading the png image with the same resolution the quality is high.