Search code examples
androidscreenshot

Screenshot compression loss of quality


Maybe someone else was faced with this problem: As the title says, when uploading screenshots from devices to our server image quality degradation is quite high. You can see one example on the following link http://cdn.voicebo.com/7507-05e6a7b3bf91d96b2d08da649c2ef590.jpg

This screenshot was taken on Nexus 4 but same thing happens on Galaxy S2, S3 and Note 2. Unfortunately we don't have more phones to test for this right now but considering popularity of following models this affect large number of our users.

I have searched for quite some time to answers or reasons why this might happen and found the following link which is not really what I was looking for but contains some information http://www.google.rs/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCYQFjAA&url=http%3A%2F%2Fandroidforums.com%2Fsamsung-galaxy-s3%2F580114-screenshot-glitch.html&ei=1dKdUbPNA8nBO7G9gPgE&usg=AFQjCNECq7UNMp16pU8WLMlLwZVb4i2Ofw

I have also came to conclusion that screenshot images are saved as png files while images from the camera are in jpeg (I think this is same for all ROMS but might be wrong) so this might be the problem too. Part I don't get is why would this be an issue, because as I understand when you read image file from any supported format you get raw bytes of data for that image so input format shouldn't play role in output compression if raw bytes were read without errors.
Relevant part of code in image compression is only this but if more info is required I can add more:

bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);

Questions I am asking are: Has anyone else faced this problem and how did you solve it? How should I compress png images (using what settings) to get best results at reasonable file size?

Bonus:I am currently trying out a way to detect which file format the image is but if someone used this to solve similar issue please mention that in answer too. Edit:How to get the Image Format of the images from Gallery is the part I am using now to get format of image but this doesn't actually answer the question. Thanks to all the guys there for useful discussion.


Solution

  • Now you've mentioned the options.inSampleSize setting, it seems incredibly likely that your problem is caused by this: setting options.inSampleSize = 4 tells the encoder to throw pixels away (apparently literally; proper resampling would look better than your example), which is exactly what you're seeing.

    You need to make some decisions about what should be reduced in size and what shouldn't - you say in your comment than this setting should be determined by input bounds, so it sounds like you're already doing this and perhaps you need some debugging there.

    I'd reiterate that changing PNGs to JPEGs might not be the best option, unless your screenshots often contain photographic content. As you may know, PNG is very poor at compressing photographic content, but conversely, JPEG is very poor at maintaining quality with the sorts of images commonly found on computer / device screens. PNG can often produce smaller files in such circumstances than acceptable JPEG images.