2

In an Android application that I am writing, I have a document image (jpeg) that is being uploaded to a server that recognizes the document and sends me back the relevant details. While all that is well and fine, the code in the server expects me to set the "Image DPI" meta-information as seen in mac like so,

Screen-shot of the meta-information of an image

The "Image DPI" that is shown in the above screenshot, isn't exactly its value. I have written a method that calculates the dpi-value. How do I set the thusly calculated dpi-value to the meta-information of my jpeg document? I have been able to set this particular meta-information in the application's iOS counterpart, but in Android, two days of relentless trying has left my errand futile.

I do know about ExifInterface, and I have been unlucky in using its setAttribute(String key,String value) method. (What should be the key? What should be the value? How do I set the unit? SHOULD I set the unit?).

I have also seen Java-related solutions to this that suggest the use of javax.imageio.*package which is simply unavailable for Android.

Has anyone faced issues like this? How do I go on about this issue?

avismara
  • 5,141
  • 2
  • 32
  • 56

1 Answers1

5

To edit the value, you need to first create a byte[] array that will store the Bitmap.compress(). Here is a part of my code where I do just that(input being the source Bitmap).

ByteArrayOutputStream uploadImageByteArray = new ByteArrayOutputStream();
input.compress(Bitmap.CompressFormat.JPEG, 100, uploadImageByteArray);
byte[] uploadImageData = uploadImageByteArray.toByteArray();

Based on the JFIF structure, you need to edit the 13th, 14th, 15th, 16th, and 17th indexes in the byte array. 13th specifying the density type, 14th and 15th the X resolution, and 16th and 17th holding the Y resolution. I got the dpi using the following method:

private long getDPIinFloat(int width, int height) {
        return (long) Math.sqrt(width * width + height * height) / 4;
}

After I got the DPI, I had to do some bit manipulation like so:

long firstPart = dpiInFloat >> 8;
if (GlobalState.debugModeOn) {
    Log.d(TAG, "First Part: " + firstPart);
}
long lastPart = dpiInFloat & 0xff;
if (GlobalState.debugModeOn) {
    Log.d(TAG, "Last Part: " + lastPart);
}

And then, manipulate the byte information like so:

uploadImageData[13] = 1;
uploadImageData[14] = (byte) firstPart;
uploadImageData[15] = (byte) lastPart;
uploadImageData[16] = (byte) firstPart;
uploadImageData[17] = (byte) lastPart;
 //Upload Image data to the server

This way, I was able to set the dpi information on the metadata.

avismara
  • 5,141
  • 2
  • 32
  • 56
  • Thank's I've implemented the code I'm getting 456 dpi image.I believe that private long getDPIinFloat(int width, int height) is the width and height of the image, I also tried to return float DP = 200, do you know where I need to insert the value to get 200 dpi? – BoazGarty Feb 12 '15 at 14:22
  • x DPI is represented by 14 and 15 position of your byte array. You need to convert the dpi information into bits which is taken part by the `firstPart` and `secondPart` variables in the code. – avismara Feb 12 '15 at 14:28