4

I create a bitmap after doing some canvas and paint operations and then Base64 encode it to a string. When I repeat the process on a separate device and compare the base64 encoded strings returned by the two devices, they are different. Any ideas on why that would be the case ?

Code that generates the bitmap -

Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.save();
canvas.rotate(45, midX, midY);
canvas.restore();
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextSize(45);
paint.setTextAlign(Align.CENTER);
paint.setTextColor(Color.parseColor(colorString));
StaticLayout staticLayout = new StaticLayout("Text", paint, width,Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
staticLayout.draw(canvas);

Code that converts the bitmap to a Base64 encoded string -

    int size = bitmap.getRowBytes() * bitmap.getHeight();
    byte[] byteArray;

    ByteBuffer byteBuffer = ByteBuffer.allocate(size);
    bitmap.copyPixelsToBuffer(byteBuffer);
    byteArray = byteBuffer.array();

    String encodedString =  Base64.encodeToString(byteArray, Base64.NO_WRAP);
Vinay Gaba
  • 861
  • 3
  • 10
  • 23
  • Are the bitmaps created in exactly the same way on both devices? In particular, are they exactly the same size (in pixels) and format? – clownba0t Jan 09 '18 at 03:16
  • @clownba0t Yes its runs through the same piece of code on both the devices so it should be identical – Vinay Gaba Jan 09 '18 at 06:48
  • The only other suggestion I have is to try writing the two raw bitmaps (i.e. the raw bytes, without doing any compression) to files and doing a hex diff (see https://stackoverflow.com/a/16380175/2259854) to determine which parts of the files are different. – clownba0t Jan 09 '18 at 07:55
  • @clownba0t I already remove the compression and convert the raw bytes to Base64 strings. Will try the hex diff and let you know. Thanks! – Vinay Gaba Jan 09 '18 at 08:39
  • You cannot base64 encode a bitmap to begin with. So tell better what you do. Or yet better show the code doing so. – greenapps Jan 09 '18 at 11:43
  • `Yes its runs through the same piece of code on both the devices so it should be identical`. That is no answer to the question. The question was if resolution and format were the same. Please answer. 'They should' is no answer. – greenapps Jan 09 '18 at 11:48
  • @greenapps Sorry about being vague. To answer your question - yes they have the same resolution and format. I have manually verified this too. – Vinay Gaba Jan 09 '18 at 20:21
  • @greenapps I get the bytes from a bitmap and then Base64 encode that. Adding code in the question. – Vinay Gaba Jan 09 '18 at 20:21
  • It is unclear how you obtain that bitmap. So already the bitmaps can be different. You should post complete reproducable code. – greenapps Jan 09 '18 at 21:10
  • @greenapps Added that as well – Vinay Gaba Jan 09 '18 at 21:27
  • The devices have different screen resolutions? – greenapps Jan 09 '18 at 21:30
  • If you put the bitmaps in an ImageView then do they look different? – greenapps Jan 09 '18 at 21:31
  • @greenapps No they look identical however when I convert their Base64 encoded strings back to an image using - http://freeonlinetools24.com/base64-image and then save those images through that website and run it through ImageMagic, I see that their color histograms are different. – Vinay Gaba Jan 09 '18 at 21:33
  • The other aspect is that the online converter that I posed above saves it to jpeg's which does not guarantee that the same images are going to remain similar since it compresses it so I'm not sure if seeing different color histograms is to be expected. – Vinay Gaba Jan 09 '18 at 21:36
  • You cannot use jpeg as it is not lossless. – greenapps Jan 09 '18 at 21:48
  • You should not use online converters to mess around with the bytes of the bitmap. You should just check if the bytes are equal. No messing around with base64 also. Just inspect the bytes. – greenapps Jan 09 '18 at 21:50
  • Yeah but I have already conclude that the bytes are not identical either. I used the convertor to check what exactly was different (header, actual colors, etc) – Vinay Gaba Jan 09 '18 at 21:54

2 Answers2

4

Even if the fonts are exactly the same, hinting (both of the character glyphs and lines) will be dependent on the underlying hardware as well as the browser.

This is a well known characteristic of the HTML canvas.

If you want to be able to generate exactly the same image on 2 different devices then you'd need to work on uint array with your own primitives for drawing / your own font handlers.

symcbean
  • 45,607
  • 5
  • 49
  • 83
2

It's not clear where the bitmap object from the second code snippet is coming from, so there could be loads of explanation.

Though, my guess is the bitmap gets converted into device pixels at some point, and that would explain why you get different results on different device, depending on screen size and resolution.

It's unlikely this is an issue with Base64 encoding method, and you could verify that by comparing the byte array.

Alex Sanséau
  • 6,440
  • 3
  • 17
  • 24