在我的应用程序中,我从服务器获取图像。现在我想将该图像转换为位图以便在屏幕上显示。为此我使用下面的代码。但它没有给我相同的图像意味着没有确切的尺寸和清晰度。它比确切的图像小。
我使用了以下代码:
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);
}
我的代码出错了?有没有其他方法可以做同样的事情?
答案 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();
现在我得到了同样质量的图像。我没有检查你的解决方案。可能也可以工作..