如何在BlackBerry中将图像转换为位图?

时间:2013-01-30 07:21:08

标签: image blackberry bitmap

在我的应用程序中,我从服务器获取图像。现在我想将该图像转换为位图以便在屏幕上显示。为此我使用下面的代码。但它没有给我相同的图像意味着没有确切的尺寸和清晰度。它比确切的图像小。

我使用了以下代码:

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;
}

这是BMPGenerator类:

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);
    }

我的代码出错了?有没有其他方法可以做同样的事情?

2 个答案:

答案 0 :(得分:2)

我相信你不需要这部分:

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);

只需使用Image获取原始ARGB数据:

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

然后使用argbData创建Bitmap

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

答案 1 :(得分:0)

谢谢你的回复。我能够以某种不同的方式解决这个问题。我正在使用这四行代码:

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

现在我得到了同样质量的图像。我没有检查你的解决方案。可能也可以工作..