Java (J2ME) 将图像转换为字节 [],然后返回图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/598046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:40:59  来源:igfitidea点击:

Java (J2ME) Convert Image to byte[], then back to Image

javaimagebyte

提问by

I'm trying to convert an Image object to a byte array then back to an Image (so that I can store the image in a blob object in an Apache Derby Database).

我正在尝试将 Image 对象转换为字节数组,然后再转换回 Image(以便我可以将图像存储在 Apache Derby 数据库中的 blob 对象中)。

I can convert an Image to a byte array (code below) but I cann't convert the bytes back to an image. As a further complication I'm using J2ME, so I can't use javax.image.*. Can you help?

我可以将图像转换为字节数组(下面的代码),但无法将字节转换回图像。更复杂的是,我使用的是 J2ME,所以我不能使用 javax.image.*。你能帮我吗?

Thanks

谢谢

package six.util;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver; 
import java.awt.Component; 
import java.awt.MediaTracker;
import java.awt.Graphics;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.PixelGrabber;
import java.util.ArrayList;

public class ImageConverter extends Component
{

private MediaTracker mediaTracker;
private Image image;

private ImageConverter(Image image)
{
    super();
    this.mediaTracker = new MediaTracker(this);
    this.mediaTracker.addImage(image, 0);
    this.image = image;
}

private BufferedImage convert()
{
    /*
     * Have to wait for image to load.
     */
    try
    {
        this.mediaTracker.waitForID(0);
    }catch(InterruptedException e)
    {

    }
    System.out.println("-1");

    GraphicsConfiguration graphicsConfig = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    BufferedImage bimage = graphicsConfig.createCompatibleImage(this.image.getWidth(null),this.image.getHeight(null));
    System.out.println("-2");
    Graphics g = bimage.getGraphics();
    g.drawImage(image, 0, 0, null);
    return bimage;
}

private static byte[] convertIntToByteArray(int integer)
{
    byte[] bytes = new byte[4];
    bytes[0] =(byte)( integer >> 24 );
    bytes[1] =(byte)( (integer << 8) >> 24 );
    bytes[2] =(byte)( (integer << 16) >> 24 );
    bytes[3] =(byte)( (integer << 24) >> 24 );
    return bytes;
}

private static int convertByteArrayToInt(byte[] bytes)
{
    return (bytes[0] << 32) | (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | bytes[4];
}

private static byte[] convertIntArrayToByteArray(int[] integers)
{
    byte[] bytes = new byte[integers.length*4];
    for (int index = 0; index < integers.length; index++)
    {
        byte[] integerBytes = convertIntToByteArray(integers[index]);
        bytes[index*4] =        integerBytes[0];
        bytes[1 + (index*4)] = integerBytes[1];
        bytes[2 + (index*4)] = integerBytes[2];
        bytes[3 + (index*4)] = integerBytes[3];
    }
    return bytes;
}

private static int[] convertByteArrayToIntArray(byte[] bytes)
{
    ArrayList integers = new ArrayList();
    for (int index = 0; index < bytes.length; index += 4)
    {
        byte[] fourBytes = new byte[4];
        fourBytes[0] = bytes[index];
        fourBytes[1] = bytes[index+1];
        fourBytes[2] = bytes[index+2];
        fourBytes[3] = bytes[index+3];
        int integer = convertByteArrayToInt(fourBytes);
        integers.add(new Integer(integer));
    }
    int[] ints = new int[bytes.length/4];
    for (int index = 0; index < integers.size() ; index++)
    {
        ints[index] = ((Integer)integers.get(index)).intValue();
    }
    return ints;
}

public static byte[] convertToBytes(Image image)
{
    System.out.println("A");
    ImageConverter converter = new ImageConverter(image);
    System.out.println("B");
    BufferedImage bufferedImage = converter.convert();
    System.out.println("C");
    PixelGrabber pixelGrabber = new PixelGrabber(image,0,0,bufferedImage.getWidth(),bufferedImage.getHeight(),true);
    System.out.println("D");
    try
    {
        if(pixelGrabber.grabPixels())
        {
            Object pixels = pixelGrabber.getPixels();
            if (pixels instanceof byte[])
            {   
                return (byte[])pixels;
            }
            return convertIntArrayToByteArray((int[])pixels);
        }
    }catch(InterruptedException e)
    {
    }
    return null;
}


 }

采纳答案by Ravi Wallau

To recreate the image you can use the method createRGBImage in the Image class (http://java.sun.com/javame/reference/apis/jsr118/), but be aware that you're using 4 bytes for each pixel in the image. A image with 200 x 200 pixels of width will have 40000 pixels in total, which will occupy 160KB of memory in the mobile device.

要重新创建图像,您可以使用 Image 类 ( http://java.sun.com/javame/reference/apis/jsr118/)中的 createRGBImage 方法,但请注意,您为图像中的每个像素使用了 4 个字节图片。宽度为 200 x 200 像素的图像总共有 40000 个像素,这将占用移动设备中 160KB 的内存。

I've worked with images in J2ME before, but only sending the images from the server to the client. In that case, you can change the resolution of the image on the server (where you have the code and the raw power to do that), encode it as JPEG and then send it to the client. The method Image.createImage(...) can create an image in any encoded format supported by the J2ME engine that is running the application. I believe that JPEG will always be accepted.

我以前在 J2ME 中处理过图像,但只将图像从服务器发送到客户端。在这种情况下,您可以在服务器上更改图像的分辨率(您拥有代码和原始能力),将其编码为 JPEG,然后将其发送到客户端。Image.createImage(...) 方法可以创建运行应用程序的 J2ME 引擎支持的任何编码格式的图像。我相信 JPEG 将永远被接受。

Even if you need those images for future use, you can save the byte[] buffer returned by the server in a Record Store and then use it.

即使您需要这些图像以备将来使用,您也可以将服务器返回的 byte[] 缓冲区保存在 Record Store 中,然后使用它。

回答by moshen

I don't know about javame, but wouldn't this work?

我不知道 javame,但这行不通?

javax.microedition.lcdui.Image.createImage(new ByteArrayInputStream(byte[]))