在XMLJavaFX中存储图像
我有一个类,我用XML保存它的数据,其中一个数据是默认情况下不能用XML保存的图像,当我读到时,我必须转换它,但我没有在图像类中找到任何在XMLJavaFX中存储图像,xml,javafx,Xml,Javafx,我有一个类,我用XML保存它的数据,其中一个数据是默认情况下不能用XML保存的图像,当我读到时,我必须转换它,但我没有在图像类中找到任何parse()方法来解组它。是否可以将图像转换为字符串并将其转换回图像 谢谢我的“示例”项目中有这个示例。(我不知道我为什么要写它。)它基本上就像@jewelsea在他的评论中描述的那样 import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.i
parse()
方法来解组它。是否可以将图像转换为字符串并将其转换回图像
谢谢我的“示例”项目中有这个示例。(我不知道我为什么要写它。)它基本上就像@jewelsea在他的评论中描述的那样
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.util.Base64;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javax.imageio.ImageIO;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.XMLEvent;
public class ImageXMLAccessor {
private final ExecutorService exec = Executors.newCachedThreadPool(r -> {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread ;
});
public void saveImage(XMLEventWriter writer, XMLEventFactory eventFactory, Image image)
throws IOException, XMLStreamException {
BufferedImage buffImage = SwingFXUtils.fromFXImage(image, null);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ImageIO.write(buffImage, "png", bytes);
String encodedImage = Base64.getEncoder().encodeToString(bytes.toByteArray());
writer.add(eventFactory.createCharacters(encodedImage));
}
public Image readImage(XMLEventReader eventReader)
throws IOException, XMLStreamException, InterruptedException, ExecutionException {
PipedInputStream pipedInput = new PipedInputStream();
FutureTask<Image> imageTask = new FutureTask<>(new Callable<Image>() {
@Override
public Image call() throws Exception {
try (InputStream imageStream = Base64.getDecoder().wrap(pipedInput)) {
BufferedImage buffImage = ImageIO.read(imageStream);
return SwingFXUtils.toFXImage(buffImage, null);
}
}
});
exec.submit(imageTask);
try (PrintWriter output = new PrintWriter(new PipedOutputStream(pipedInput))) {
for (boolean done = false ; eventReader.hasNext() && ! done; ) {
XMLEvent event = eventReader.nextEvent();
if (event.isCharacters()) {
Characters characters = event.asCharacters();
String data = characters.getData();
output.write(data);
} else if (event.isEndElement()) {
output.close();
done = true ;
}
}
}
return imageTask.get();
}
}
导入java.awt.image.buffereImage;
导入java.io.ByteArrayOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.PipedInputStream;
导入java.io.PipedOutputStream;
导入java.io.PrintWriter;
导入java.util.Base64;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.FutureTask;
导入javafx.embed.swing.SwingFXUtils;
导入javafx.scene.image.image;
导入javax.imageio.imageio;
导入javax.xml.stream.XMLEventFactory;
导入javax.xml.stream.XMLEventReader;
导入javax.xml.stream.XMLEventWriter;
导入javax.xml.stream.XMLStreamException;
导入javax.xml.stream.events.Characters;
导入javax.xml.stream.events.XMLEvent;
公共类ImageXMLAccessor{
private final ExecutorService exec=Executors.newCachedThreadPool(r->{
螺纹=新螺纹(r);
setDaemon(true);
返回线程;
});
public void saveImage(XMLEventWriter编写器、XMLEventFactory eventFactory、图像图像)
抛出IOException、XMLStreamException{
buffereImage buffImage=SwingFXUtils.fromFXImage(image,null);
ByteArrayOutputStream字节=新建ByteArrayOutputStream();
写入(buffImage,“png”,字节);
字符串encodedImage=Base64.getEncoder().encodeToString(bytes.toByteArray());
add(eventFactory.createCharacters(encodedImage));
}
公共映像读取映像(XMLEventReader-eventReader)
抛出IOException、XMLStreamException、InterruptedException、ExecutionException{
PipedInputStream pipedInput=新的PipedInputStream();
FutureTask imageTask=新的FutureTask(新的可调用(){
@凌驾
公共映像调用()引发异常{
尝试(InputStream imageStream=Base64.getDecoder().wrap(pipedInput)){
BuffereImage buffImage=ImageIO.read(imageStream);
返回SwingFXUtils.toFXImage(buffImage,null);
}
}
});
执行提交(图像任务);
try(PrintWriter输出=新的PrintWriter(新的PipedOutputStream(pipedInput))){
for(boolean done=false;eventReader.hasNext()&&!done;){
XMLEvent=eventReader.nextEvent();
if(event.isCharacters()){
Characters=event.asCharacters();
字符串数据=个字符。getData();
输出。写入(数据);
}else if(event.isEndElement()){
output.close();
完成=正确;
}
}
}
返回imageTask.get();
}
}
这是一个使用它的测试程序。可以打开JPG或PNG文件,然后将其另存为XML(或打开结构类似的XML文件):
导入java.io.File;
导入java.io.IOException;
导入java.io.Writer;
导入java.nio.file.Files;
导入javafx.application.application;
导入javafx.application.Platform;
导入javafx.beans.property.ObjectProperty;
导入javafx.beans.property.SimpleObject属性;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.stage.FileChooser;
导入javafx.stage.FileChooser.ExtensionFilter;
导入javafx.stage.stage;
导入javax.xml.namespace.QName;
导入javax.xml.stream.FactoryConfigurationError;
导入javax.xml.stream.XMLEventFactory;
导入javax.xml.stream.XMLEventReader;
导入javax.xml.stream.XMLEventWriter;
导入javax.xml.stream.XMLInputFactory;
导入javax.xml.stream.XMLOutputFactory;
导入javax.xml.stream.XMLStreamException;
导入javax.xml.stream.events.StartElement;
导入javax.xml.stream.events.XMLEvent;
公共类ImageXMLTest扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
ImageXMLAccessor accessor=新的ImageXMLAccessor();
FileChooser chooser=新建FileChooser();
chooser.getExtensionFilters().add(新的ExtensionFilter(“图像文件”,“*.jpg”,“*.jpg”,“*.png”,“*.png”));
添加(新的ExtensionFilter(“XML文件”、“*.XML”、“*.XML”));
按钮打开按钮=新按钮(“打开…”);
ObjectProperty currentImage=新的SimpleObject属性();
openButton.setOnAction(事件->{
File imageFile=chooser.showOpenDialog(primaryStage);
if(imageFile!=null){
if(imageFile.toString().toLowerCase().endsWith(“.xml”)){
openFromXMLFile(imageFile、currentImage、访问器);
}否则{
openFromImageFile(imageFile,currentImage);
}
}
});
Button saveButton=新建按钮(“保存到XML…”);
saveButton.setOnAction(事件->{
File xmlFile=chooser.showsavedilog(primaryStage);
如果(xmlFile!=null){
试一试{
saveImageToXML(存取器,currentImage,xmlFile);
}捕获(例外e){
e、 printStackTrace();
}
}
});
saveButton.disableProperty().bind(currentImage.isNull());
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
public class ImageXMLTest extends Application {
@Override
public void start(Stage primaryStage) {
ImageXMLAccessor accessor = new ImageXMLAccessor();
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.jpg", "*.JPG", "*.png", "*.PNG"));
chooser.getExtensionFilters().add(new ExtensionFilter("XML files", "*.xml", "*.XML"));
Button openButton = new Button("Open...");
ObjectProperty<Image> currentImage = new SimpleObjectProperty<>();
openButton.setOnAction(event -> {
File imageFile = chooser.showOpenDialog(primaryStage);
if (imageFile != null) {
if (imageFile.toString().toLowerCase().endsWith(".xml")) {
openFromXMLFile(imageFile, currentImage, accessor);
} else {
openFromImageFile(imageFile, currentImage);
}
}
});
Button saveButton = new Button("Save to XML...");
saveButton.setOnAction(event -> {
File xmlFile = chooser.showSaveDialog(primaryStage);
if (xmlFile != null) {
try {
saveImageToXML(accessor, currentImage, xmlFile);
} catch (Exception e) {
e.printStackTrace();
}
}
});
saveButton.disableProperty().bind(currentImage.isNull());
HBox controls = new HBox(5, openButton, saveButton);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
ImageView imageView = new ImageView();
imageView.setFitHeight(600);
imageView.setFitWidth(800);
imageView.setPreserveRatio(true);
imageView.imageProperty().bind(currentImage);
BorderPane root = new BorderPane(imageView, null, null, controls, null);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
private void saveImageToXML(ImageXMLAccessor accessor,
ObjectProperty<Image> currentImage, File xmlFile)
throws IOException, FactoryConfigurationError, XMLStreamException {
Writer writer = Files.newBufferedWriter(xmlFile.toPath());
XMLEventFactory eventFactory = XMLEventFactory.newFactory();
XMLEventWriter eventWriter = XMLOutputFactory.newFactory().createXMLEventWriter(writer);
eventWriter.add(eventFactory.createStartDocument());
QName imageElement = new QName("image");
eventWriter.add(eventFactory.createStartElement(imageElement, null, null));
accessor.saveImage(eventWriter, eventFactory, currentImage.get());
eventWriter.add(eventFactory.createEndElement(imageElement, null));
eventWriter.add(eventFactory.createEndDocument());
writer.close();
}
private void openFromImageFile(File imageFile,
ObjectProperty<Image> currentImage) {
try {
currentImage.set(new Image(imageFile.toURI().toURL().toExternalForm(), true));
} catch (Exception exc) {
exc.printStackTrace();
}
}
public void openFromXMLFile(File xmlFile, ObjectProperty<Image> currentImage, ImageXMLAccessor accessor) {
new Thread(() -> {
XMLInputFactory inputFactory = XMLInputFactory.newFactory() ;
XMLEventReader eventReader = null ;
try {
eventReader = inputFactory.createXMLEventReader(Files.newBufferedReader(xmlFile.toPath()));
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
StartElement startEl = event.asStartElement();
if ("image".equals(startEl.getName().getLocalPart())) {
Image image;
try {
image = accessor.readImage(eventReader);
Platform.runLater(() -> currentImage.set(image));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (eventReader != null ){
try {
eventReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
public static void main(String[] args) {
launch(args);
}
}