Java 将内存中的 Image 转换为 Blob

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20961065/
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-13 05:34:41  来源:igfitidea点击:

converting Image in memory to a Blob

javaimageoraclejax-ws

提问by user3167187

I have an Image (type: java.awt.Image) in memory, I want to convert it to a Blob (type: java.sql.Blob) using jdk 1.7.

我在内存中有一个图像(类型:java.awt.Image),我想使用 jdk 1.7 将它转换为 Blob(类型:java.sql.Blob)。

Everything I've been able to find on this subject uses streams and files. Surely I don't need to save this Image to a file before being able to convert it??

我能在这个主题上找到的所有东西都使用流和文件。当然,在能够转换它之前,我不需要将此图像保存到文件中?

Not much to show here, but an example follows:

这里不多展示,但示例如下:

import java.sql.Blob; import java.awt.Image;

导入 java.sql.Blob; 导入 java.awt.Image;

public GenericResponseType savePhoto(Image image)
{
       Connection conn = ds.getConnection();

       << some DB code and assembly of PreparedStatement >>

       Blob blob = conn.createBlob();

           << here's where the magic needs to happen I need to get the image parameter to blob >>
           // I've tried the following but doesn't quite work as it wants a RenderedImage
       // OutputStream os = blob.setBinaryStream(1);
       // ImageIO.write(parameters.getPhoto().getImage(), "jpg", os);


       pstmt.setBlob(4, blob);
     }

Some more detail (though I doubt it matters much) is that the above is generated using web services/JAX-WS from WSDL with an operation declared using MTOM. So it generates a signature with an Image being passed as a variable.

一些更详细的信息(尽管我怀疑它很重要)是上述内容是使用来自 WSDL 的 Web 服务/JAX-WS 和使用 MTOM 声明的操作生成的。所以它生成一个签名,其中一个 Image 作为变量传递。

回答by MadProgrammer

java.awt.Imageis pretty simply. It does not provide any means by which the image can be written/saved nor does it provide any means to get access to underlying pixel data of the image.

java.awt.Image很简单。它不提供任何可以写入/保存图像的方法,也不提供任何方法来访问图像的底层像素数据。

The first step, is converting the java.awt.Imageto something that ImageIOcan support. This will allow you to write the image data out...

第一步,是将 转换为可以支持的java.awt.Image东西ImageIO。这将允许您将图像数据写出...

ImageIOrequires a RenderedImageas it's primary image source. BufferedImageis the only implementation of this interface within the default libraries...

ImageIO需要 aRenderedImage作为它的主要图像源。 BufferedImage是默认库中此接口的唯一实现...

Unfortunately, there's no simply method for converting from one to the other. Fortunately, it's not to hard.

不幸的是,没有简单的方法可以从一种转换到另一种。幸运的是,这并不难。

Image img = ...;

BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();

Basically, this just paints the original java.awt.Imageonto the BufferedImage

基本上,这只是将原件java.awt.Image绘制到BufferedImage

Next, we need to save the image in some way so that it can produce a InputStream...

接下来,我们需要以某种方式保存图像,以便它可以生成InputStream...

This is a little less then optimal, but gets the job done.

这有点不那么理想,但可以完成工作。

ByteArrayOutputStream baos = null;
try {
    baos = new ByteArrayOutputStream();
    ImageIO.write(bi, "png", baos);
} finally {
    try {
        baos.close();
    } catch (Exception e) {
    }
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

Basically, we write the image out to a ByteArrayOutputStreamand the use the result to generate a ByteArrayInputStream

基本上,我们将图像写入 aByteArrayOutputStream并使用结果生成一个ByteArrayInputStream

Now. If memory is an issue or the image is rather large, you can first write the image to a Fileand then simply read the Fileback in via some kind of InputStreaminstead...

现在。如果内存有问题或图像相当大,您可以先将图像写入 a File,然后File通过某种方式简单地读回InputStream...

Finally, we set the InputStreamto the required column...

最后,我们将 设置InputStream为所需的列...

PreparedStatement stmt = null;
//...    
stmt.setBlob(parameterIndex, bais);

And Blob's your uncle...

而 Blob 是你的叔叔......

回答by Java Devil

Try the following: (probably a much easier process, this was just what I found after a quick goolge and cannot guarantee it'll work - Mads answer looks much more credible).

尝试以下操作:(可能是一个更简单的过程,这正是我在快速使用谷歌之后发现的,不能保证它会起作用 - Mads 的回答看起来更可信)。

  1. Get a BufferedImage (From this answer)

    BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
    buffered.getGraphics().drawImage(image, 0, 0 , null);
    
  2. Get a byte array (From this answer)

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(buffered, "jpg", baos );
    byte[] imageInByte = baos.toByteArray();
    
  3. Save byte array as blob (From this answer) (but will should probably use a Prepared Statement)

    Blob blob = connection.createBlob();
    blob.setBytes(1, imageInByte);
    
  1. 获取一个 BufferedImage(来自这个答案

    BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
    buffered.getGraphics().drawImage(image, 0, 0 , null);
    
  2. 获取一个字节数组(来自这个答案

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(buffered, "jpg", baos );
    byte[] imageInByte = baos.toByteArray();
    
  3. 将字节数组另存为 blob(来自此答案)(但可能应该使用准备好的语句)

    Blob blob = connection.createBlob();
    blob.setBytes(1, imageInByte);