如何从JavaFX ImageView获取byte[]?

15

我该如何从JavaFX的Image/ImageView类获取byte[]?我希望将我的图像存储为Blob到数据库中。这是我用来完成此操作的方法:

 public PreparedStatement prepareQuery(HSQLDBConnector connector) {
        try {
            Blob logoBlob = connector.connection.createBlob();
            logoBlob.setBytes(0,logo.getImage());//stuck  here
            for (int i = 0, a = 1; i < data.length; i++, a++) {

                connector.prepStatCreateProfile.setString(a, data[i]);

            }
            //store LOB

            connector.prepStatCreateProfile.setBlob(11, logoBlob);

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return connector.prepStatCreateProfile;
    }

是否有一种方法可以将我的当前对象(imageview)中的图像转换为byte[]?或者我应该考虑使用其他类来处理我的图像,或者是通过引用指向位置并使用路径/ URL进行处理?

3个回答

15

试试这个:

BufferedImage bImage = SwingFXUtils.fromFXImage(logo.getImage(), null);
ByteArrayOutputStream s = new ByteArrayOutputStream();
ImageIO.write(bImage, "png", s);
byte[] res  = s.toByteArray();
s.close(); //especially if you are using a different output stream.

取决于标志类,应该可以工作。

在编写和读取时,您需要指定格式,据我所记,不支持bmp格式,因此最终将在数据库中得到一个png字节数组。


谢谢,我担心我必须使用一些swing的方法。但我认为这样做可以行得通,但是有没有纯JavaFX的方法来完成这个任务?或者这是从图像获取byte[]的JavaFX完全推荐的方法吗? - Tomas Bisciak
1
是的,有一个纯Java FX解决方案,但对我来说是未知领域。 - Lorenzo Boccaccia
我有一个byte[]数组。如何使用这个byte[]数组加载ImageView? - Mubasher
2
Image.write 的文档说明如下:该方法在写入操作完成后不会关闭提供的 OutputStream;如果需要,调用方有责任关闭流。这表明必须关闭 ByteArrayOutputStream 或使用 try-with-ressource 块。 - Oliver Jan Krylow
如何将整个 ImageView 转换为字节数组而不是 Image - Faizan Mubasher
为什么你想要那个?一个包含图像视图属性的结构在这种情况下更合适。你可以创建一个可序列化对象,其中包含所有的imageview属性、图像字节数组并对其进行序列化。添加一个重新创建imageview的方法,然后就完成了。 - Lorenzo Boccaccia

8

纯Java FX解决方案追踪(==您将需要填写缺失的点:)

Image i = logo.getImage();
PixelReader pr = i.getPixelReader();
PixelFormat f = pr.getPixelFormat();

WriteablePixelFromat wf = f.getIntArgbInstance(); //???

int[] buffer = new int[size as desumed from the format f, should be  i.width*i.height*4];

pr.getPixels(int 0, int 0, int i.width, i.height, wf, buffer, 0, 0);

如果您使用了以下代码, WritablePixelFormat<ByteBuffer> wf = PixelFormat.getByteBgraInstance();那么在执行以下代码时, pr.getPixels(0, 0, (int) (i.getWidth()), (int) i.getHeight(), wf, buffer, 0, (int)(4*i.getWidth())); scanlineStride 的值需要设置为 4*image.getwidth()。 - usertest
我不明白,blob输出在哪里? - Tal Kohavy
在 int[] 缓冲区中 - Lorenzo Boccaccia

3

洛伦佐的答案是正确的,本答案仅考虑效率和可移植性方面。

根据图像类型和存储需求,将图像转换为压缩格式进行存储可能更加高效,例如:

ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
ImageIO.write(SwingFXUtils.fromFXImage(fxImage, null), "png", byteOutput);
Blob logoBlob = connector.connection.createBlob();
logoBlob.setBytes(0, byteOutput.toByteArray());

在将图像存储之前,将其转换为像png这样的通用格式的另一个优点是,处理数据库的其他程序可以读取该图像,而不必尝试从JavaFX特定的字节数组存储格式进行转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接