简体   繁体   English

如何转换清单 <String> Java中将字符串转换为BufferedImage

[英]How to convert List<String> of Strings to BufferedImage in Java

I want to convert a Base64 String array to a BufferedImage . 我想将Base64 String数组转换为BufferedImage The approach I tried to accomplish: 我尝试完成的方法:

static BufferedImage decodeToImage(List<String> imageStrings) {
    BufferedImage image = null;
    ByteBuffer imageByteBuffer = ByteBuffer.allocate(500000000);
    try {
        BASE64Decoder decoder = new BASE64Decoder();
        for (String imageString : imageStrings) {
            imageByteBuffer.put(imageString.getBytes());
        }

        ByteArrayInputStream bis = new ByteArrayInputStream(imageByteBuffer.array());
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}

I want to return a BufferedImage but it returns null. 我想返回一个BufferedImage但它返回null。

You can just use this: 您可以使用以下命令:

public static BufferedImage decodeToImage(List<String> imageStrings) {
    try {
        byte[] bytes = Base64.getDecoder().decode(String.join("", imageStrings));
        return ImageIO.read(new ByteArrayInputStream(bytes));
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

Have you looked at what are you getting in? 你看过你要做什么吗?

Cause this code 导致此代码

public static void main(String[] args) {
    String base64String = "data:image/png;base64,iVBORw0...=";
    String[] strings = base64String.split(",");
    List<String> param = new ArrayList<String>();
    param.add(strings[1]);
    BufferedImage bi = decodeToImage(param);
    System.out.println("BufferedImage: " + bi);
}

static BufferedImage decodeToImage(List<String> imageStrings) {
    BufferedImage image = null;
    ByteBuffer imageByteBuffer = ByteBuffer.allocate(500000000);
    try {
        for (String imageString : imageStrings) {
          imageByteBuffer.put(DatatypeConverter.parseBase64Binary(imageString));
        }
        ByteArrayInputStream bis = new ByteArrayInputStream(imageByteBuffer.array());
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        System.out.println("error?");
        e.printStackTrace();
    }
    return image;
}

Will print 将打印

BufferedImage: BufferedImage@7eda2dbb: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@6576fe71 transparency = 3 has alpha = true isAlphaPre = false ByteInterleavedRaster: width = 302 height = 232 #numDataElements 4 dataOff[0] = 3 BufferedImage:BufferedImage @ 7eda2dbb:type = 6 ColorModel:#pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@6576fe71透明度= 3 has alpha = true isAlphaPre = false ByteInterleavedRaster:width = 302 height = 232 #numDataElements 4个dataOff [0] = 3

But if I just give it the whole base64 text, with the image info in front 但是,如果我只给它整个base64文本,并且图像信息在前面

 public static void main(String[] args) {
    String base64String = "data:image/png;base64,iVBORw0...=";
    String[] strings = base64String.split(",");
    List<String> param = new ArrayList<String>();
    param.add(base64String); //THIS IS THE DIFFERENT LINE
    BufferedImage bi = decodeToImage(param);
    System.out.println("BufferedImage: " + bi);
    }

It will print null 它将打印null

Replace base64String with a valid base 64 encoded png from 将base64String替换为来自的有效base 64编码的png

http://freeonlinetools24.com/base64-image http://freeonlinetools24.com/base64-image

I cut it down in this example cause otherwise it becomes several thousand characters long. 我在此示例中将其缩减,因为否则它将变成数千个字符。

Is the maximum length of a string in Java really a problem for your code? Java中字符串的最大长度真的对您的代码有问题吗? If not, I'd simplify your code like this (and fix the decoding bug): 如果没有,我会像这样简化您的代码(并修复解码错误):

static BufferedImage decodeToImage(String imageString) {
    try {
        BASE64Decoder decoder = new BASE64Decoder();    
        return ImageIO.read(new ByteArrayInputStream(decoder.decode(imageString)));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

Or, if you really have a problem with the length of the strings (Base64 does produce output longer than the input, so it may make sense in extreme cases, but verify this, as it otherwise complicates your code unnecessary), keep the list of strings. 或者,如果您确实对字符串的长度有疑问(Base64的输出长度长于输入,因此在极端情况下可能有意义,但请进行验证,否则将使您的代码变得不必要),请保留以下列表:字符串。 I'd simply skip the ByteBuffer and use a ByteArrayOutputStream instead, as it's much easier to work with. 我只是跳过ByteBuffer而是使用ByteArrayOutputStream ,因为使用起来要容易得多。

static BufferedImage decodeToImage(List<String> imageStrings) {
    try {
        ByteArrayOuputStream buffer = new ByteArrayOuputStream();

        BASE64Decoder decoder = new BASE64Decoder();
        for (String imageString : imageStrings) {
            buffer.write(decoder.decode(imageString));
        }

        return ImageIO.read(new ByteArrayInputStream(buffer.toArray()));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

PS: While you should generally close streams, the close() method on ByteArrayInputStream and ByteArrayOutputStream are no-ops. PS:虽然通常应该关闭流,但是ByteArrayInputStreamByteArrayOutputStream上的close()方法是禁止操作的。

Buffers are little bit tricky to work with. 缓冲区有点棘手。 Might be a good idea to take a look here: https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip() 最好在这里看看: https//docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip()

As far as I can remember you have to prepare the buffer before you can read it; 据我所记得,您必须先准备好缓冲区,然后才能读取它。 the position of the internal 'cursor' has to be set to the start position from where you then can read 'capacity' bytes. 必须将内部“光标”的位置设置为起始位置,然后您才能从该位置读取“容量”字节。 Well, as I said: As far as I can remember. 好吧,正如我所说:据我所记得。 It's more then twelve years ago I had to directly work with buffers. 大约十二年前,我不得不直接使用缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM