[SPRING] 서버 측 이미지 생성 용 JavaFX
SPRING서버 측 이미지 생성 용 JavaFX
이상하게 들릴지 모르지만 JavaFX를 사용하여 서버 측에서 차트 이미지를 생성하려고합니다. JavaFX에는 이미지 변환 조인과 위치 지정을 수행하는 멋진 캔버스 API가 있기 때문입니다.
특히 봄 MVC 서비스를 사용하여 내 차트를 이미지로 생성합니다. 주된 문제점은 편리한 Spring 빈에서 javaFX API를 호출하는 방법이다. Java 응용 프로그램 (javaFX 응용 프로그램 클래스를 확장하지 않음)에서 javafx 코드를 실행하려고하면
java.lang.IllegalStateException: Toolkit not initialized
이 문제를 해결하는 방법에 대한 제안이나 아이디어가 있습니까?
해결법
-
==============================
1.그래서 몇 가지 연구를 한 후에 JavaFX로 캔버스 그리기를 구현했으며 여기에 간단한 예제가 있습니다.
그래서 몇 가지 연구를 한 후에 JavaFX로 캔버스 그리기를 구현했으며 여기에 간단한 예제가 있습니다.
먼저 별도의 스레드에서 시작되는 JavaFX 응용 프로그램을 만들었습니다 (저는 Spring taskExecutor를 사용하지만 일반 Java 스레드를 사용할 수 있습니다).
public class ChartGenerator extends Application { private static Canvas canvas; private static volatile byte[] result; public static void initialize(TaskExecutor taskExecutor) { taskExecutor.execute(new Runnable() { @Override public void run() { launch(ChartGenerator.class); } }); } public static synchronized byte[] generateChart(final Object... params) { Platform.runLater(new Runnable() { @Override public void run() { ByteArrayOutputStream baos = null; try { GraphicsContext gc = canvas.getGraphicsContext2D(); gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); /** * Do the work with canvas **/ final SnapshotParameters snapshotParameters = new SnapshotParameters(); snapshotParameters.setFill(Color.TRANSPARENT); WritableImage image = canvas.snapshot(snapshotParameters, null); BufferedImage bImage = SwingFXUtils.fromFXImage(image, null); baos = new ByteArrayOutputStream(); ImageIO.write(bImage, chartType.outputFormat, baos); result = baos.toByteArray(); } catch (InstantiationException e) { throw new ChartGenerationException(e); } catch (IllegalAccessException e) { throw new ChartGenerationException(e); } catch (NoSuchMethodException e) { throw new ChartGenerationException(e); } catch (InvocationTargetException e) { throw new ChartGenerationException(e); } catch (IOException e) { throw new ChartGenerationException(e); } finally { IOUtils.closeQuietly(baos); } } }); while (result == null) { //wait } byte[] ret = result; result = null; return ret; } @Override public void start(Stage stage) { canvas = new Canvas(); } public static class ChartGenerationException extends RuntimeException { public ChartGenerationException(String message) { super(message); } public ChartGenerationException(Throwable cause) { super(cause); } } }
그런 다음 Spring 애플리케이션이 시작될 때 initialize () 메소드를 호출한다.
@Autowired private TaskExecutor taskExecutor; @PostConstruct private void initChartGenerator() { ChartGenerator.initialize(taskExecutor); }
물론이 솔루션은 비 Spring 애플리케이션으로 포팅 될 수 있습니다.
이것은 단일 스레드 솔루션 (제 경우에는 충분합니다)이지만 다중 스레드 사용 (아마도 draw 메소드를 호출하기 위해 RMI를 사용할 수도 있습니다)에 채택 될 수 있다고 생각합니다.
또한이 솔루션은 내 Windows 워크 스테이션에서 "있는 그대로"작동하지만 Linux 서버 환경에서 몇 가지 추가 작업이 호출되어야합니다.
추신 이 솔루션을 사용하여 서버 측에서 다른 JavaFX 기능 (예 : HTML 내보내기)을 사용할 수도 있습니다.
-
==============================
2.다른 사람들이 이것을 찾고있는 경우에, 이것은 훨씬 간단한 방법입니다. JavaFX 2.2를 사용하여 다음 작업을 수행 할 수있었습니다.
다른 사람들이 이것을 찾고있는 경우에, 이것은 훨씬 간단한 방법입니다. JavaFX 2.2를 사용하여 다음 작업을 수행 할 수있었습니다.
waitForInit = new Semaphore(0); root = new Group(); root.getChildren().add(jfxnode); FxPlatformExecutor.runOnFxApplication(() -> { snapshot = jfxnode.snapshot(new SnapshotParameters(), null); waitForInit.release(); }); waitForInit.acquireUninterruptibly(); BufferedImage bi = SwingFXUtils.fromFXImage(snapshot, null);
노드를 그룹에 추가 할 필요가 없습니다. 거기에서 이미지로 원하는 모든 작업을 수행 할 수 있습니다.
FxPlatformExecutor는 프로젝트에 사용중인 JME3-JFX 라이브러리에서 가져온 것입니다. 참조 : https://github.com/empirephoenix/JME3-JFX/blob/master/src/main/java/com/jme3x/jfx/FxPlatformExecutor.java
runOnFxApplication () 메서드를 만들거나 FxPlatformExecutor 클래스를 쉽게 만들 수 있습니다.
여기에 코드가 있습니다.
package com.jme3x.jfx; import javafx.application.Platform; /** * TODO This Class should be replaced by some Workmanager implemntation * in the future * @author Heist */ public class FxPlatformExecutor { public static void runOnFxApplication(Runnable task) { if (Platform.isFxApplicationThread()) { task.run(); } else { Platform.runLater(task); } } }
나는이 코드를 작성하지 않았다. github 링크는 위에있다.
-
==============================
3.아마도이 솔루션과 비슷한 것이 도움이 될까요?
아마도이 솔루션과 비슷한 것이 도움이 될까요?
JavaFX 2.1 : 툴킷이 초기화되지 않았습니다.
그렇지 않으면 서비스를 만들고 데이터 저장소로 이미지를 푸시하고 스프링 응용 프로그램에서 이미지를 가져 오는 것을 고려할 것입니다.
희망은 적어도 조금 도움을 제공합니다!
from https://stackoverflow.com/questions/17940329/javafx-for-server-side-image-generation by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] org.hibernate.LazyInitializationException : 프록시를 초기화 할 수 없습니다 - 세션 없음, 프레임 없음 (0) | 2019.01.14 |
---|---|
[SPRING] Spring을 사용하여 EhCache 인스턴스 가져 오기 ... 지능적으로 (0) | 2019.01.14 |
[SPRING] RESTful 끝점에 대한 스프링 폼 기반 로그인을 비활성화하려면 어떻게합니까? (0) | 2019.01.14 |
[SPRING] 스프링 XML 구성 파일에서 Java Date 객체를 초기화하는 방법은 무엇입니까? (0) | 2019.01.14 |
[SPRING] Spring을 사용하여 인증이 필요한 MongoDB에 연결하는 방법 (0) | 2019.01.14 |