2

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.

Community
  • 1
  • 1
Igor Čordaš
  • 5,785
  • 4
  • 42
  • 54
  • PNG is a lossless format (it has compression, but it won't make any difference to the image quality), so what you're getting out is what you're putting in. You typically only get limited control over PNG compression settings, if any. Your problem appears to be that the screen grabbing algorithm is only taking a small proportion of the available pixels... or your resolution is being deliberately reduced somewhere else in the pipeline. More info (how are you taking the screen grabs, how are they sent to your server, etc.) might help. Is this actually a programming (i.e. StackOverflow) problem? – Bob Sammers May 23 '13 at 09:41
  • EDIT: stupid 5min. rule Thank you for response. Yes this is a programing question even thou the link submitted is actually not about programing but user detected behavior. Screenshots are not grabbed by our application but user makes them using options available in ROM, on samsung devices screnshoot key combos are available, S2 has vol- power for example. These are the images that user can pick to upload in our application picking "from gallery option". I know about lossliness of PNG and that is the part that puzzles the most since I get worst results from lossless then lossy formats. – Igor Čordaš May 23 '13 at 09:51
  • If your users take a screenshot and then view the resulting file on the device, does it show the same problem? You said that the screen grabs were PNGs but the example you've provided is a JPEG. Where (and why) was this conversion made? – Bob Sammers May 23 '13 at 10:09
  • Try taking Sceenshot from Eclipse – Nargis May 23 '13 at 10:12
  • Screenshots that user get on their device are great to good quality (some phones apparently don't capture true colors and blur images a bit but images are still ok so thats not a problem). In our app we are making a conversion to JPEG with the settings provided in code block, this is done in order to save bandwidth and space on servers since for example images from 8MP cameras are just huge. After conversion resulting jpeg is sent to server. Loss of quality is only apperent with screen-shots since images downloaded from internet and uploaded to server don't degrade that much. – Igor Čordaš May 23 '13 at 10:24
  • You're putting camera images through the same pipeline and not seeing an equivalent problem? Does re-compressing 8MP jpegs at quality 90 result in much change in file size? I can't see it would unless you're also reducing the pixel count ...which would cause the effects you're seeing with the PNGs. For typical desktop graphics, PNGs can often be smaller that JPEGs and they're always higher quality, so one option is to detect PNG files and not recompress. It also occurs to me that Bitmap.Compress() might only be compressing the first frame of an interlaced PNG, but that's only supposition. – Bob Sammers May 23 '13 at 11:29
  • @Bob SammersYou are absolutely correct about the pixel count and I think that is the problem because I am using options.inSampleSize = 4; but actually this size should be calculated according to input bounds. Thank you for pointing me in the right direction. What do you mean "Bitmap.Compress() might only be compressing the first frame of an interlaced PNG" I think screenshots are not interlaced by default? – Igor Čordaš May 23 '13 at 11:40
  • I'd ignore what I said about interlacing. It didn't seem very likely and now you've mentioned changing the SampleSize parameter, I think you should concentrate on this: see my answer – Bob Sammers May 23 '13 at 12:39
  • 1
    http://stackoverflow.com/questions/24135445/pre-guess-size-of-bitmap-from-the-actual-uri-before-scale-loading – Fattie May 11 '16 at 15:39

1 Answers1

2

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.

Bob Sammers
  • 3,080
  • 27
  • 33
  • Thank you for your input, that was the problem and I solved it by doing things suggested on http://developer.android.com/training/displaying-bitmaps/load-bitmap.html so now I calculate inSampleSize based on input image and don't loose pixels if I don't have to. I do know that there is no much point in converting PNG->JPEG and that two formats are used for diffrent purposes but this is requirement of our server and images like screenshots stay good in jpeg. I marked your answer as accepted (yeeey for first answered question). – Igor Čordaš May 23 '13 at 12:50