Yan_Yan
Yan_Yan

Reputation: 67

JavaFX How to use and scale an image/icon without quality loss?

I need to work with some elements in my JavaFX-application, that use

This application should run on multiple devices with different screen resolutions, and i also (eventually) need to scale the images/icons (force them to match a certain size/proportion). So how could this be done with a minimum of quality loss? I know, that it's not possible to load SVG-graphics into an image-view, so i probably have to use png/jpg. Should i use multiple versions of the iage/icon in different sizes? Or can i scale one HIGH RESOLUTION image down to 1/3 of its size without quality loss? (Btw. is it maybe possible to use SVGs with css?)

Upvotes: 1

Views: 1185

Answers (2)

mipa
mipa

Reputation: 10650

If you are using Eclipse you could install the e(fx)clipse plugin which, among other things, provides a tool to convert normal SVG-files to FXML-files which can then be loaded directly into JavaFX. This is my standard procedure for vector based graphics which needs scaling.

Upvotes: 1

Przemek Krysztofiak
Przemek Krysztofiak

Reputation: 924

I believe svg path is scalable without quality loss.

fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.Group?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.SVGPath?>


<VBox xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <StackPane prefHeight="400.0" prefWidth="400.0">
         <children>
            <Group fx:id="iconGroup">
               <children>
                  <SVGPath content="M12 6c1.11 0 2-.9 2-2 0-.38-.1-.73-.29-1.03L12 0l-1.71 2.97c-.19.3-.29.65-.29 1.03 0 1.1.9 2 2 2zm4.6 9.99l-1.07-1.07-1.08 1.07c-1.3 1.3-3.58 1.31-4.89 0l-1.07-1.07-1.09 1.07C6.75 16.64 5.88 17 4.96 17c-.73 0-1.4-.23-1.96-.61V21c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-4.61c-.56.38-1.23.61-1.96.61-.92 0-1.79-.36-2.44-1.01zM18 9h-5V7h-2v2H6c-1.66 0-3 1.34-3 3v1.54c0 1.08.88 1.96 1.96 1.96.52 0 1.02-.2 1.38-.57l2.14-2.13 2.13 2.13c.74.74 2.03.74 2.77 0l2.14-2.13 2.13 2.13c.37.37.86.57 1.38.57 1.08 0 1.96-.88 1.96-1.96V12C21 10.34 19.66 9 18 9z" />
               </children>
            </Group>
         </children>
      </StackPane>
      <HBox>
         <children>
            <Button mnemonicParsing="false" onAction="#onMinusButton" text="-0.5" />
            <Button mnemonicParsing="false" onAction="#onPlusButton" text="+0.5" />
         </children>
      </HBox>
   </children>
</VBox>

code:

    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.stage.Stage;

    public class SvgIconApp extends Application {

        private final SvgIconViewController controller = new SvgIconViewController();

        public static void main(String[] args) {
            launch(args);
        }

        @Override
        public void start(Stage stage) throws Exception {
            FXMLLoader fxmlLoader = new FXMLLoader(SvgIconApp.class.getResource("/svgiconview.fxml"));
            fxmlLoader.setController(controller);
            fxmlLoader.load();
            Scene scene = new Scene(fxmlLoader.getRoot());
            stage.setScene(scene);
            stage.show();
        }
    }

    class SvgIconViewController {

        @FXML
        private Group iconGroup;

        @FXML
        private void onPlusButton(ActionEvent actionEvent) {
            double newScale = iconGroup.getScaleX() + 0.5;
            iconGroup.setScaleX(newScale);
            iconGroup.setScaleY(newScale);
        }

        @FXML
        private void onMinusButton(ActionEvent actionEvent) {
            double newScale = iconGroup.getScaleX() - 0.5;
            iconGroup.setScaleX(newScale);
            iconGroup.setScaleY(newScale);
        }
    }

Upvotes: 1

Related Questions