【问题标题】:JavaFX play gif image in ImageViewJavaFX 在 ImageView 中播放 gif 图像
【发布时间】:2017-10-27 17:41:56
【问题描述】:

我看到这个问题问了很多,但我还没有看到一个非常普遍的方法。我正在使用 JavaFX 在 Java Eclipse Oxygen 中开发一个桌面应用程序,并且我有一个加载程序,我想在任何时候显示该加载程序,并且通过 http 加载图像。当用户点击不同的行时,必须通过 http 加载图像。因此,我将加载器放在图像顶部,然后使用; productPreviewLoader.setVisible(true) 显示或隐藏它。 fxml 中的 loader ImageView 在 GridPane 中是这样的。

<GridPane>
   <columnConstraints>
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
   </columnConstraints>
   <rowConstraints>
      <RowConstraints minHeight="10.0" valignment="TOP" vgrow="ALWAYS" />
      <RowConstraints vgrow="SOMETIMES" />
      <RowConstraints vgrow="SOMETIMES" />
   </rowConstraints>
   <children>
      <ImageView fx:id="productPreview" fitHeight="282.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
      <!-- This is the loader-->
      <ImageView fx:id="productPreviewLoader" fitHeight="112.0" fitWidth="136.0" pickOnBounds="true" preserveRatio="true" /> 
      <TextFlow fx:id="productPreviewTextFlow" GridPane.rowIndex="1">
         <GridPane.margin>
            <Insets right="10.0" />
         </GridPane.margin>
         <padding>
            <Insets bottom="30.0" left="10.0" right="10.0" top="30.0" />
         </padding></TextFlow>

设置加载器图像的代码如下所示;

//Set up the product preview image loader
BufferedImage bufferedImage;
File file = new File("resources\\images\\loaders\\img-loader-icon.gif");
try {
bufferedImage = ImageIO.read(file);
   productPreviewLoader.setImage(SwingFXUtils.toFXImage(bufferedImage, null));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
productPreviewLoader.setVisible(false);

图像无法在 ImageView 中播放。如果不可能,请告诉我另一种方法。另外,我在让 ImageView 在 GridPane 行中水平居中 ImageView 时遇到问题。每当调整窗口大小时,GridPane 都会调整大小以匹配其父级的高度。我知道这是 2 个问题,但我可能最终会创建 2 个问题。

【问题讨论】:

    标签: java xml javafx


    【解决方案1】:

    您还没有提供一个完整的示例,我可以使用它来展示如何将 gif 图像加载到 ImageView 的用例,所以我将给您一个完整的示例:

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;
    
    import javafx.application.Application;
    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.FlowPane;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class GifViewerTest extends Application {
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage stage) throws Exception {
    
            VBox box = new VBox();
            ImageView imageView = new ImageView();
    
            box.getChildren().add(imageView);
    
            Button localLoadButton = new Button("Local load");
            Button externalLoadButton = new Button("URL Load");
    
            localLoadButton.setOnAction(e -> {
                imageView.setImage(new Image(this.getClass().getResource("java.gif").toExternalForm()));
            });
    
            externalLoadButton.setOnAction(e -> {
                String imageSource = "https://cdn.dribbble.com/users/550761/screenshots/1773241/untitled-5.gif";
                try {
                    imageView.setImage(createImage(imageSource));
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            });
    
            FlowPane buttonPane = new FlowPane();
            buttonPane.setAlignment(Pos.CENTER);
            buttonPane.getChildren().addAll(localLoadButton, externalLoadButton);
    
            box.getChildren().add(buttonPane);
    
            stage.setScene(new Scene(box, 500, 400));
            stage.show();
        }
    
        private Image createImage(String url) throws IOException {
            // You have to set an User-Agent in case you get HTTP Error 403
            // respond while you trying to get the Image from URL.
            URLConnection conn = new URL(url).openConnection();
            conn.setRequestProperty("User-Agent", "Wget/1.13.4 (linux-gnu)");
    
            try (InputStream stream = conn.getInputStream()) {
                return new Image(stream);
            }
        }
    }
    

    如果您的所有图片都是通过 URL 加载的,那么为什么不使用 WebViewer 并加载 URL 而不是使用 ImageView?如果 gif 大小不小,会导致 GUI 延迟,直到从 InputStream 加载 gif 图像,在这种情况下,您应该将加载过程创建到后台线程,但正如我所说,如果您只使用 WebViewer,您可以避免所有这些。

    【讨论】:

    • 查看这段代码,我看不到您在哪里设置了要播放的 git 动画。除非您添加了按钮来加载图像。我没有加载图像的问题。添加到 ImageView 时,图像不会播放。它停留在第一帧。
    • “玩”到底是什么意思?当您使用上面的代码并单击“URL 加载”按钮时,您应该会看到 gif 图像。 externalLoadButton 通过 URL 将 gif Image 加载到 ImageView 中。也许我不明白你的目标。如果我错了,请纠正我。
    • gif 图像包含动画。在我的代码中,当我使用productPreviewLoader.setImage(SwingFXUtils.toFXImage(bufferedImage, null)); 时,图像仍然没有动画
    • 当然可以。上面的代码正在播放一个动画 gif 图像,你可以在这个 link 中找到它。为了播放动画图像,您可以按照我从资源中执行的方式加载它,也可以直接通过 URL 加载它。您是说使用我提供的代码仍然无法看到动画?
    • 这很奇怪,我想我已经完成了。所以只是做productPreviewLoader.setImage(new Image("file:resources\\images\\loaders\\img-loader-icon.gif")); 应该加载一个正在播放的图像。在您的回答中,我认为这不适用于本地图像this.getClass().getResource("java.gif").toExternalForm() 我假设您正在尝试通过 HTTP 加载本地图像而不是图像。
    猜你喜欢
    • 2012-07-10
    • 2018-07-19
    • 2021-11-14
    • 2012-03-18
    • 2017-05-06
    • 1970-01-01
    • 2019-12-03
    • 2015-03-20
    • 1970-01-01
    相关资源
    最近更新 更多