Arindam Mukherjee
Arindam Mukherjee

Reputation: 2285

How to Convert the Image to Bitmap in BlackBerry?

In my application, I am getting the Image from the server. Now i want to convert that Image to Bitmap for displaying in the screen. For that i am using below codes. But it is not giving me the same image means not with exact dimension and clarity. It is coming smaller than the exact image.

I have used the below codes:

private Bitmap getBitmapFromImg(Image img) {
    Bitmap bmp = null;
    try {
        Logger.out(TAG, "It is inside the the image conversion        " +img);
        Image image = Image.createImage(img);
        byte[] data = BMPGenerator.encodeBMP(image);
        Logger.out(TAG, "It is inside the the image conversion---333333333"+data);
        bmp = Bitmap.createBitmapFromBytes(data, 0, data.length, 1);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return bmp;
}

Here is the BMPGenerator class:

public final class BMPGenerator {

    /**
     * @param image
     * @return
     * @throws IOException
     * @see {@link #encodeBMP(int[], int, int)}
     */
    public static byte[] encodeBMP(Image image) throws IOException {
            int width = image.getWidth();
            int height = image.getHeight();
            int[] rgb = new int[height * width];
            image.getRGB(rgb, 0, width, 0, 0, width, height);
            return encodeBMP(rgb, width, height);
    }

    /**
     * A self-contained BMP generator, which takes a byte array (without any unusual
     * offsets) extracted from an {@link Image}. The target platform is J2ME. You may
     * wish to use the convenience method {@link #encodeBMP(Image)} instead of this.
     * <p>
     * A BMP file consists of 4 parts:-
     * <ul>
     * <li>header</li>
     * <li>information header</li>
     * <li>optional palette</li>
     * <li>image data</li>
     * </ul>
     * At this time only 24 bit uncompressed BMPs with Windows V3 headers can be created.
     * Future releases may become much more space-efficient, but will most likely be
     * ditched in favour of a PNG generator.
     * 
     * @param rgb
     * @param width
     * @param height
     * @return
     * @throws IOException
     * @see http://en.wikipedia.org/wiki/Windows_bitmap
     */
    public static byte[] encodeBMP(int[] rgb, int width, int height)
                    throws IOException {
            int pad = (4 - (width % 4)) % 4;
            // the size of the BMP file in bytes
            int size = 14 + 40 + height * (pad + width * 3);
            ByteArrayOutputStream bytes = new ByteArrayOutputStream(size);
            DataOutputStream stream = new DataOutputStream(bytes);
            // HEADER
            // the magic number used to identify the BMP file: 0x42 0x4D
            stream.writeByte(0x42);
            stream.writeByte(0x4D);
            stream.writeInt(swapEndian(size));
            // reserved
            stream.writeInt(0);
            // the offset, i.e. starting address of the bitmap data
            stream.writeInt(swapEndian(14 + 40));
            // INFORMATION HEADER (Windows V3 header)
            // the size of this header (40 bytes)
            stream.writeInt(swapEndian(40));
            // the bitmap width in pixels (signed integer).
            stream.writeInt(swapEndian(width));
            // the bitmap height in pixels (signed integer).
            stream.writeInt(swapEndian(height));
            // the number of colour planes being used. Must be set to 1.
            stream.writeShort(swapEndian((short) 1));
            // the number of bits per pixel, which is the colour depth of the image.
            stream.writeShort(swapEndian((short) 24));
            // the compression method being used.
            stream.writeInt(0);
            // image size. The size of the raw bitmap data. 0 is valid for uncompressed.
            stream.writeInt(0);
            // the horizontal resolution of the image. (pixel per meter, signed integer)
            stream.writeInt(0);
            // the vertical resolution of the image. (pixel per meter, signed integer)
            stream.writeInt(0);
            // the number of colours in the colour palette, or 0 to default to 2n.
            stream.writeInt(0);
            // the number of important colours used, or 0 when every colour is important;
            // generally ignored.
            stream.writeInt(0);
            // PALETTE
            // none for 24 bit depth
            // IMAGE DATA
            // starting in the bottom left, working right and then up
            // a series of 3 bytes per pixel in the order B G R.
            for (int j = height - 1; j >= 0; j--) {
                    for (int i = 0; i < width; i++) {
                            int val = rgb[i + width * j];
                            stream.writeByte(val & 0x000000FF);
                            stream.writeByte((val >>> 8) & 0x000000FF);
                            stream.writeByte((val >>> 16) & 0x000000FF);
                    }
                    // number of bytes in each row must be padded to multiple of 4
                    for (int i = 0; i < pad; i++) {
                            stream.writeByte(0);
                    }
            }
            byte[] out = bytes.toByteArray();
            bytes.close();
            // quick consistency check
            if (out.length != size)
                    throw new RuntimeException("bad math");
            return out;
    }

    /**
     * Swap the Endian-ness of a 32 bit integer.
     * 
     * @param value
     * @return
     */
    private static int swapEndian(int value) {
            int b1 = value & 0xff;
            int b2 = (value >> 8) & 0xff;
            int b3 = (value >> 16) & 0xff;
            int b4 = (value >> 24) & 0xff;

            return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
    }

    /**
     * Swap the Endian-ness of a 16 bit integer.
     * 
     * @param value
     * @return
     */
    private static short swapEndian(short value) {
            int b1 = value & 0xff;
            int b2 = (value >> 8) & 0xff;

            return (short) (b1 << 8 | b2 << 0);
    }

Where is wrong in my code?? Is there any other way to do the same??

Upvotes: 0

Views: 269

Answers (2)

Arindam Mukherjee
Arindam Mukherjee

Reputation: 2285

Thanks Armihed For your reply. I am able to resolve this some different way. I am using this four lines of code:

Image image = Image.createImage(img);
byte[] data = BMPGenerator.encodeBMP(image);
EncodedImage encodeimage = EncodedImage.createEncodedImage(data, 0, data.length);
bmp = encodeimage.getBitmap();

Now i am getting the same quality image. I did not check your solution. May be that also can work..

Upvotes: 0

Vit Khudenko
Vit Khudenko

Reputation: 28418

I believe you don't need this part:

Image image = Image.createImage(img);
byte[] data = BMPGenerator.encodeBMP(image);
Logger.out(TAG, "It is inside the the image conversion---333333333"+data);
bmp = Bitmap.createBitmapFromBytes(data, 0, data.length, 1);

Just use Image to get the raw ARGB data:

int width = image.getWidth();
int height = image.getHeight();
int[] argbData = new int[height * width];
image.getRGB(argbData, 0, width, 0, 0, width, height);

Then use argbData to create a Bitmap:

Bitmap b = new Bitmap(width, height);
b.setARGB(argbData, 0, width, 0, 0, width, height);

Upvotes: 2

Related Questions