2

I've converted an bitmap image into string to save it:

............
Bitmap photo = extras.getParcelable("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);

Then I retrieve the bitmap from string to set an activity's background just like that:

byte[] temp = Base64.decode(encodedImage, Base64.DEFAULT);
Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeByteArray(temp, 0,
                temp.length, options);
Drawable d = new BitmapDrawable(getResources(), bitmap);
getWindow().setBackgroundDrawable(d);

Everything works fine but the image quality reduces tremendously. How can I keep the image quality same as the original image? Did I do something wrong here that have reduced the quality?

Developer Kid
  • 71
  • 1
  • 1
  • 13

2 Answers2

11

JPEG is lossy, no matter what quality settings you use. If you want to keep the image unchanged, you have to use lossless compression. for example Bitmap.CompressFormat.PNG

msh
  • 2,700
  • 1
  • 17
  • 23
8

You are having here a tradeoff situation between picture quality and memory usage. Take a look at this line:

photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);

photo.compress is obviously decreasing your image resolution in a factor given by the second parameter, unfortunately, this is the best quality you can get, since between 0 - 100, 100 stands for the best quality you can get. Now, you have another option, depending on the original picture's size you can just save the image without compressing it, but be aware that most cases this doesn't work and Jalvik can throw an OutofMemoryException, hope this helps.

Daniel Conde Marin
  • 7,588
  • 4
  • 35
  • 44
  • So the problem is in storing the image, not the retrieving? – Developer Kid May 25 '13 at 01:38
  • Of course, you are reducing your image quality when you compress it, in order to have a smaller byteArrayOutputStream and avoid memory issues – Daniel Conde Marin May 25 '13 at 01:41
  • 1
    Daniel is right. One note more for you to understand this better. JPEG is frequency based compression and it is not very edge friendly. Your edges are going to be very damaged. You can best see this on texts. Image compression is always a bargain between quality and size. – Marko Lazić May 25 '13 at 01:47
  • I saved this bitmap in string format in `SharedPreference` (which is another bad habit as `SharedPreference` is not suitable for such large string). So can I store the bitmap in `sqlite` database without loosing quality? – Developer Kid May 25 '13 at 01:49
  • Take a look at android's media store, is a good solution, of course that sharedprefs is not an option, this is the link: http://developer.android.com/reference/android/provider/MediaStore.html – Daniel Conde Marin May 25 '13 at 01:51
  • I am going to save the image in `sqlite` database. Is there any better option than storing it in sqlite? It is just only one image – Developer Kid May 25 '13 at 03:28
  • I have solved it by `photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);` and saved it in a file of internal storage. Thanks for your suggestion! – Developer Kid May 25 '13 at 09:45