{"id":2307,"date":"2013-01-02T20:22:16","date_gmt":"2013-01-02T19:22:16","guid":{"rendered":"http:\/\/sahits.ch\/blog\/?p=2307"},"modified":"2013-01-02T20:22:16","modified_gmt":"2013-01-02T19:22:16","slug":"javafx-deformation-with-offscreen-image","status":"publish","type":"post","link":"http:\/\/sahits.ch\/blog\/blog\/2013\/01\/02\/javafx-deformation-with-offscreen-image\/","title":{"rendered":"JavaFX: Deformation with offscreen image"},"content":{"rendered":"<p>As stated in my <a href=\"http:\/\/sahits.ch\/blog\/?p=2286\">last article<\/a>, I tried to render the writing part off screen to create an image off of it and then deform that.<\/p>\n<p><!--more--><\/p>\n<p>That&#8217;s what I did with this result:<\/p>\n<p><a href=\"http:\/\/sahits.ch\/blog\/?attachment_id=2308\" rel=\"attachment wp-att-2308\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-2308\" alt=\"JavaFX_twolines_offscreenimage\" src=\"http:\/\/sahits.ch\/blog\/wp-content\/uploads\/2013\/01\/JavaFX_twolines_offscreenimage-300x176.png\" width=\"300\" height=\"176\" srcset=\"http:\/\/sahits.ch\/blog\/wp-content\/uploads\/2013\/01\/JavaFX_twolines_offscreenimage-300x176.png 300w, http:\/\/sahits.ch\/blog\/wp-content\/uploads\/2013\/01\/JavaFX_twolines_offscreenimage.png 966w\" sizes=\"auto, (max-width: 300px) 85vw, 300px\" \/><\/a>Turn&#8217;s out that this is almost the same result as when applying the lines to a group with a transparent background and then transform it:<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/sahits.ch\/blog\/?attachment_id=2292\" rel=\"attachment wp-att-2292\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-2292 alignnone\" alt=\"JavaFX_two_line_deformed\" src=\"http:\/\/sahits.ch\/blog\/wp-content\/uploads\/2013\/01\/JavaFX_two_line_deformed-300x176.png\" width=\"300\" height=\"176\" srcset=\"http:\/\/sahits.ch\/blog\/wp-content\/uploads\/2013\/01\/JavaFX_two_line_deformed-300x176.png 300w, http:\/\/sahits.ch\/blog\/wp-content\/uploads\/2013\/01\/JavaFX_two_line_deformed.png 966w\" sizes=\"auto, (max-width: 300px) 85vw, 300px\" \/><\/a><\/p>\n<p>However for completeness sake here is the code for the off screen example. It seams that the margins at the left and top look a bit better:<\/p>\n<pre class=\"brush:java\">package ch.sahits.javafx.test.stretch;\r\n\r\nimport ch.sahits.javafx.test.ResizeableCanvas;\r\nimport java.io.IOException;\r\nimport java.util.logging.Level;\r\nimport java.util.logging.Logger;\r\nimport javafx.application.Application;\r\nimport javafx.scene.Group;\r\nimport javafx.scene.Scene;\r\nimport javafx.scene.control.Label;\r\nimport javafx.scene.control.LabelBuilder;\r\nimport javafx.scene.effect.PerspectiveTransform;\r\nimport javafx.scene.effect.PerspectiveTransformBuilder;\r\nimport javafx.scene.image.Image;\r\nimport javafx.scene.image.ImageView;\r\nimport javafx.scene.image.WritableImage;\r\nimport javafx.scene.paint.Color;\r\nimport javafx.scene.shape.Rectangle;\r\nimport javafx.scene.shape.RectangleBuilder;\r\nimport javafx.stage.Stage;\r\n\r\npublic class OffScreenImageGeneration extends Application {\r\n\r\n    @Override\r\n    public void start(Stage primaryStage) {\r\n        try {\r\n            Group root = new Group();\r\n            Image img = new Image(getClass().getResource(\"PaperScroll.png\").openStream());\r\n            final double width = img.getWidth();\r\n            final double height = img.getHeight();\r\n            Scene scene = new Scene(root, width, height);\r\n            ImageView imageView = new ImageView(img);\r\n            WritableImage image = createOffScreenImage();\r\n\r\n            PerspectiveTransform perspectiveTransform = PerspectiveTransformBuilder.create()\r\n                    .ulx(200).uly(0)\r\n                    .urx(544).ury(19)\r\n                    .llx(0).lly(403)\r\n                    .lrx(559).lry(502)\r\n                    .build();\r\n\r\n            ImageView imageView2 = new ImageView(image);\r\n            imageView2.setTranslateX(366);\r\n            imageView2.setTranslateY(29);\r\n            imageView2.setEffect(perspectiveTransform);\r\n\r\n            root.getChildren().addAll(imageView, imageView2);     \r\n            primaryStage.setTitle(\"Perspective Transform\");\r\n            primaryStage.setScene(scene);\r\n            primaryStage.show();\r\n        } catch (IOException ex) {\r\n            Logger.getLogger(ResizeableCanvas.class.getName()).log(Level.SEVERE, null, ex);\r\n        }\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        launch(args);\r\n    }\r\n\r\n    private WritableImage createOffScreenImage() {\r\n        Group offScreenRoot = new Group();\r\n        Scene offScreen = new Scene(offScreenRoot, 559, 502);\r\n        RectangleBuilder rectBuilder = RectangleBuilder.create()\r\n                .opacity(0.5)\r\n                .fill(Color.RED)\r\n                .width(559)\r\n                .height(502);\r\n        Rectangle untransformed = rectBuilder.build();\r\n        Label line1 = LabelBuilder.create()\r\n                .text(\"First Line\")\r\n                .style(\"-fx-font-size: 24px\")\r\n                .translateX(10)\r\n                .translateY(20)\r\n                \/\/.effect(perspectiveTransform)\r\n                .build();\r\n        Label line2 = LabelBuilder.create()\r\n                .text(\"Second Line\")\r\n                .style(\"-fx-font-size: 24px\")\r\n                .translateX(10)\r\n                .translateY(50)\r\n                \/\/.effect(perspectiveTransform)\r\n                .build();\r\n        offScreenRoot.getChildren().addAll(untransformed, line1, line2);\r\n        WritableImage image = new WritableImage((int)offScreen.getWidth(), (int)offScreen.getHeight());\r\n        offScreen.snapshot(image);\r\n        return image;\r\n    }\r\n}<\/pre>\n<p>All the heavy work is done by the createOffScreenImage method, where a second scene is created with a group of the exact measures of the rectangle to be deformed.<\/p>\n<p>And here the other code:<\/p>\n<pre class=\"brush:java\">package ch.sahits.javafx.test.stretch;\r\n\r\nimport ch.sahits.javafx.test.ResizeableCanvas;\r\nimport java.io.IOException;\r\nimport java.util.logging.Level;\r\nimport java.util.logging.Logger;\r\nimport javafx.application.Application;\r\nimport javafx.scene.Group;\r\nimport javafx.scene.GroupBuilder;\r\nimport javafx.scene.Scene;\r\nimport javafx.scene.control.Label;\r\nimport javafx.scene.control.LabelBuilder;\r\nimport javafx.scene.effect.PerspectiveTransform;\r\nimport javafx.scene.effect.PerspectiveTransformBuilder;\r\nimport javafx.scene.image.Image;\r\nimport javafx.scene.image.ImageView;\r\nimport javafx.scene.paint.Color;\r\nimport javafx.scene.shape.Rectangle;\r\nimport javafx.scene.shape.RectangleBuilder;\r\nimport javafx.stage.Stage;\r\n\r\npublic class PerpectiveTransformEffectTest extends Application {\r\n\r\n    @Override\r\n    public void start(Stage primaryStage) {\r\n        try {\r\n            Group root = new Group();\r\n            Image img = new Image(getClass().getResource(\"PaperScroll.png\").openStream());\r\n            final double width = img.getWidth();\r\n            final double height = img.getHeight();\r\n            Scene scene = new Scene(root, width, height);\r\n            ImageView imageView = new ImageView(img);\r\n\r\n            RectangleBuilder rectBuilder = RectangleBuilder.create()\r\n                    .translateX(366)\r\n                    .translateY(29)\r\n                    .opacity(0.5)\r\n                    .fill(Color.RED)\r\n                    .width(559)\r\n                    .height(502);\r\n\r\n            PerspectiveTransform perspectiveTransform = PerspectiveTransformBuilder.create()\r\n                    .ulx(200).uly(0)\r\n                    .urx(544).ury(19)\r\n                    .llx(0).lly(403)\r\n                    .lrx(559).lry(502)\r\n                    .build();\r\n\r\n            Label line1 = LabelBuilder.create()\r\n                    .text(\"First Line\")\r\n                    .style(\"-fx-font-size: 24px\")\r\n                    .translateX(20)\r\n                    .translateY(40)\r\n                    .build();\r\n\r\n            Label line2 = LabelBuilder.create()\r\n                    .text(\"Second Line\")\r\n                    .style(\"-fx-font-size: 24px\")\r\n                    .translateX(20)\r\n                    .translateY(70)\r\n                    .build();\r\n\r\n            Rectangle transparent = rectBuilder.build();\r\n            transparent.setOpacity(0);\r\n\r\n            Group text = GroupBuilder.create()\r\n                    .translateX(366)\r\n                    .translateY(29)\r\n                    .children(transparent, line1, line2)\r\n                    .effect(perspectiveTransform)\r\n                    .build();\r\n\r\n            root.getChildren().addAll(imageView, text);     \r\n            primaryStage.setTitle(\"Perspective Transform\");\r\n            primaryStage.setScene(scene);\r\n            primaryStage.show();\r\n        } catch (IOException ex) {\r\n            Logger.getLogger(ResizeableCanvas.class.getName()).log(Level.SEVERE, null, ex);\r\n        }\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        launch(args);\r\n    }\r\n}<\/pre>\n<p>Which of the two are better is hard to say, however I would guess that the one with the off screen image would be better when thinking about scaling the scene.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As stated in my last article, I tried to render the writing part off screen to create an image off of it and then deform that.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,6],"tags":[257,63,252,258,259],"class_list":["post-2307","post","type-post","status-publish","format-standard","hentry","category-java","category-programmieren","tag-deform","tag-image","tag-javafx","tag-projection","tag-screen-shot"],"_links":{"self":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/comments?post=2307"}],"version-history":[{"count":4,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2307\/revisions"}],"predecessor-version":[{"id":2312,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2307\/revisions\/2312"}],"wp:attachment":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/media?parent=2307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/categories?post=2307"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/tags?post=2307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}