Lorsqu'une instance de ʻImage` est créée normalement, l'image est chargée de manière synchrone (aucun traitement n'est renvoyé tant que le chargement n'est pas terminé).
Si l'image est petite, il n'y a pas de problème particulier, mais si une grande image est affichée, le traitement est interrompu pendant un certain temps, ce qui peut nuire à l'opérabilité.
ʻPour charger une image dans l'instance Image en arrière-plan, spécifiez
truepour l'argument du constructeur
backgroundLoading. Il existe deux constructeurs qui peuvent spécifier
backgroundLoading`.
Si vous créez une instance avec true
pour backgroundLoading
, l'image sera chargée de manière asynchrone.
Cela permet au processus de se poursuivre sans s'arrêter.
Si vous placez simplement la charge en arrière-plan, l'image ne sera pas affichée tant que le chargement n'est pas terminé.
Si la taille est grande et que le chargement prend beaucoup de temps, le fait qu'aucune image ne s'affiche peut être gênant pour l'utilisateur. Par conséquent, il peut être bon d'afficher la progression de la charge avec une barre de progression ou autre.
La classe ʻImage` peut connaître la progression du chargement progress Offrir des propriétés. Si vous l'utilisez, vous pouvez afficher la progression du chargement assez facilement.
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<BorderPane style="-fx-padding: 10px;" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.javafx.MainController">
<center>
<VBox alignment="CENTER" minHeight="0.0" minWidth="0.0" BorderPane.alignment="CENTER">
<children>
<ProgressBar fx:id="progressBar" maxWidth="1.7976931348623157E308" progress="0.0" />
<ImageView fx:id="imageView" fitHeight="200.0" fitWidth="300.0" pickOnBounds="true" preserveRatio="true" />
</children>
</VBox>
</center>
</BorderPane>
MainController.java
package sample.javafx;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ResourceBundle;
public class MainController implements Initializable {
@FXML
private ProgressBar progressBar;
@FXML
private ImageView imageView;
public void initStage(Stage stage) {
stage.setWidth(500);
stage.setHeight(400);
}
@Override
public void initialize(URL location, ResourceBundle resources) {
progressBar.managedProperty().bind(progressBar.visibleProperty());
progressBar.visibleProperty().bind(progressBar.progressProperty().lessThan(1));
imageView.managedProperty().bind(imageView.visibleProperty());
imageView.visibleProperty().bind(progressBar.progressProperty().isEqualTo(1));
Image image = new Image(Paths.get("./image/shirakawago.jpg ").toUri().toString(), true);
progressBar.progressProperty().bind(image.progressProperty());
imageView.setImage(image);
}
}
C'est un peu rapide et déroutant, mais la barre de progression s'affiche pendant le chargement de l'image et l'image s'affiche lorsque le chargement est terminé.
ProgressBar
à côté de ʻImageView` pour l'affichage de l'imageMainController.java
progressBar.managedProperty().bind(progressBar.visibleProperty());
progressBar.visibleProperty().bind(progressBar.progressProperty().lessThan(1));
imageView.managedProperty().bind(imageView.visibleProperty());
imageView.visibleProperty().bind(progressBar.progressProperty().isEqualTo(1));
visible
pour afficher uniquement la barre de progression pendant le chargement et uniquement l'image lorsque le chargement est terminé.visible
est obtenu en se liant à la valeur de la propriété progress
de la barre de progression.MainController.java
Image image = new Image(Paths.get("./image/shirakawago.jpg ").toUri().toString(), true);
progressBar.progressProperty().bind(image.progressProperty());
--Spécifiez true
pour backgroundLoading
dans l'argument du constructeur lors de la génération de ʻImage`
progress
de ʻImage à la propriété
progress` de la barre de progressionLe chargement en arrière-plan peut être utilisé non seulement en chargeant l'image actuellement affichée, mais aussi en préchargeant l'image à afficher ensuite.
Dans ce cas, seule l'instance ʻImage est générée en arrière-plan, et lors du changement d'image, l'instance ʻImage
est remplacée par ʻensembleImage () ʻof ʻImageView`.
image
@FXML
private ImageView imageView;
private Image nextImage;
public void initialize(URL location, ResourceBundle resources) {
//Chargez l'image suivante en arrière-plan
nextImage = new Image("next-image.jpg ", true);
Image initialImage = new Image("initial-image.jpg ", true);
imageView.setImage(initialImage);
}
@FXML
public void nextPage() {
//Définir la prochaine image chargée
imageView.setImage(nextImage);
}
Même les images lourdes peuvent être affichées rapidement en les chargeant à l'avance, ce qui peut conduire à une amélioration de l'opérabilité.
Il est à noter que le préchargement peut améliorer la vitesse d'affichage, mais au prix d'une consommation de mémoire accrue.
En particulier, il est à noter qu'il existe une grande différence entre la taille de l'image sur le disque et la taille lorsqu'elle est chargée en mémoire. Sur le disque, par exemple, une image JPEG a une taille considérablement compressée, alors qu'elle est décompressée lorsqu'elle est chargée en mémoire avec ʻImage`.
Je vais étudier à quel point c'est différent.
Voici la taille sur le disque, environ 6,5 Mo.
Chargez cette image avec ʻImage, puis effectuez un vidage de tas pour voir combien de mémoire l'image chargée par ʻImage
utilise.
L'analyseur de mémoire Eclipse a été utilisé pour enquêter sur le vidage du tas.
La platformImage
dans ʻImage` ressemble à ça, alors allez regarder à l'intérieur.
com.sum.prism.Image
ressemble à ça, alors allez voir à l'intérieur.
La taille des pixels de l'image est stockée en «largeur» et «hauteur».
De plus, il semble que pixelBuffer
stocke les données d'image dans un tableau d'octets, alors regardez à l'intérieur.
Cela ressemble à un bingo. «capacité» est «36366672» (environ 35 Mo). Quand je l'ai recherché, «hb» était un tableau de «byte», et il semble que toutes les données d'image aient été stockées.
Cette taille de «36 636 672» correspond exactement à la taille de «longueur x largeur x 3» dans l'image.
(4,288 * 2,848 = 12,212,224
, 12,212,224 * 3 = 36,636,672
)
En d'autres termes, toutes les données RVB (3 octets) de tous les pixels sont chargées.
La taille du disque est d'environ 6,5 Mo, mais une fois chargée en mémoire, elle est assez grande avec 35 Mo.
Je pense que la différence de taille entre le disque et la mémoire variera en fonction du format de compression de l'image d'origine et de la présence ou non du canal alpha (transparence).
ʻImage` vous permet de spécifier la taille de l'image et de la charger.
En utilisant cela, les images peuvent être chargées dans une taille plus petite que l'original, de sorte que la consommation de mémoire peut être réduite. Cependant, veuillez noter qu'elle ne sera pas affichée avec la même qualité que l'image d'origine car elle sera chargée dans une petite taille.
Le chargement en arrière-plan peut améliorer la vitesse d'affichage, mais vous devez également faire attention à la consommation de mémoire lors de l'utilisation du cache par préchargement.
Recommended Posts