我们可以使用
创建FX Image对象byte [] bytes = ------; //valid image in bytes
javafx.scene.image.Image image = new Image(new ByteArrayInputStream(bytes));
这可以设置为ImageView。
我需要相反的 ,不用 将其首先转换为 BufferedImage (SwingFXUtils.fromFXImage(image,null ))。
这样我就可以直接将字节写入文件。
我尝试了以下内容:
PixelReader pixelReader = image.getPixelReader();
int width = (int)image.getWidth();
int height = (int)image.getHeight();
byte[] buffer = new byte[width * height * 4];
pixelReader.getPixels(
0,
0,
width,
height,
PixelFormat.getByteBgraInstance(),
buffer,
0,
width * 4
);
但是,通过写 byte []缓冲区生成的文件不是有效图像。
对此有何见解?
编辑: How to get byte[] from javafx imageView提供的解决方案无法应用于我的问题。正如我已经清楚地提到过,我不想使用SwingFXUtils将其转换为BufferedImage。 此外,我想将其转换为字节数组,以便可以将其写入图像文件。
答案 0 :(得分:6)
这是稍后的方式,但如果有人想要查找,请尝试:
// Load the Image into a Java FX Image Object //
Image img = new Image(new FileInputStream("SomeImageFile.png") );
// Cache Width and Height to 'int's (because getWidth/getHeight return Double) and getPixels needs 'int's //
int w = (int)img.getWidth();
int h = (int)img.getHeight();
// Create a new Byte Buffer, but we'll use BGRA (1 byte for each channel) //
byte[] buf = new byte[w * h * 4];
/* Since you can get the output in whatever format with a WritablePixelFormat,
we'll use an already created one for ease-of-use. */
img.getPixelReader().getPixels(0, 0, w, h, PixelFormat.getByteBgraInstance(), buf, 0, w * 4);
/* Second last parameter is byte offset you want to start in your buffer,
and the last parameter is stride (in bytes) per line for your buffer. */
答案 1 :(得分:0)
使用ByteArrayInputStream
创建JavaFX Image
仅在supported formats中使用原始的,未修改的图像文件字节(bmp,jpg,gif,png)起作用。
使用PixelReader
读取Image
之后,字节数组将包含原始图像字节,这些原始图像字节只能使用WritableImage
写回到PixelWriter
,即为什么使用ByteArrayInputStream
会产生无效的图像。
以下是使用此image的可复制示例:
// Original image bytes
File file = new File("F:/Downloads/duke.png");
byte[] fileBytes = Files.readAllBytes(file.toPath());
System.out.println(fileBytes.length); // 17776 bytes
InputStream in = new ByteArrayInputStream(fileBytes);
Image image = new Image(in);
ImageView view = new ImageView(image);
VBox pane = new VBox();
pane.getChildren().add(view); // Works
in.close();
// PixelReader generated image bytes
int width = (int) image.getWidth();
int height = (int) image.getHeight();
byte[] pixelBytes = new byte[width * height * 4];
System.out.println(pixelBytes.length); // 367928 bytes
image.getPixelReader().getPixels(0, 0, width, height,
PixelFormat.getByteBgraInstance(),
pixelBytes, 0, width * 4);
Image image2 = new Image(new ByteArrayInputStream(pixelBytes));
ImageView view2 = new ImageView(image2);
pane.getChildren().add(view2); // Won't work
// PixelWriter generated image
WritableImage image3 = new WritableImage(width, height);
image3.getPixelWriter().setPixels(0, 0, width, height,
PixelFormat.getByteBgraInstance(),
pixelBytes, 0, width * 4);
ImageView view3 = new ImageView(image3);
pane.getChildren().add(view3); // Works
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
PixelReader
图像是原始图像格式,比原始图像大得多,因此,如果将这些图像存储在数据库中并且担心空间,则应尝试存储原始文件字节。否则,SwingFXUtils
类仍可用于转换回压缩格式。
写回PixelReader
图像字节时的另一个问题是,您必须以某种方式将宽度和高度存储为数据库中的单独字段,或者作为额外字节在图像字节数组上添加/添加。