如何在 javafx 的 imageView 中填充图像?
How to fill an image in an imageView in javafx?
我的数据库中保存了一张图像,该图像作为字节数组传递给图像,然后加载到图像视图。但是,我无法让它填充 imageView。我使用以下代码:
package com.example.AppPrototipo.ui.tourist;
imports...
@Component
public class ExperienceController {
@FXML
Pane imagePane;
@FXML
ImageView imageViewPrincipal;
private final ExperienceRepository experienceRepository;
public ExperienceController(ExperienceRepository experienceRepository) {
this.experienceRepository = experienceRepository;
}
@FXML
private void initialize(){
Experience experience = experienceRepository.findById(1);
Image image = new Image(new ByteArrayInputStream(experience.getImages().get(0).getImageData()));
imageViewPrincipal.setImage(image);
imageViewPrincipal.fitWidthProperty().bind(imagePane.widthProperty());
imageViewPrincipal.fitHeightProperty().bind(imagePane.heightProperty());
}
}
这是我得到的结果:
期望的结果是图像通过裁剪顶部和底部并保持居中来填充整个宽度(填充黑色边)。有人能帮我吗?
假设您在 ImageView 上将 preserveRatio 属性 设置为 true,并且正如 matt 所述是他的评论,您只需要设置其中之一,例如 fitWidth 和 fitHeight将使用图像比例进行计算。
问题是图像和窗格的比例不匹配,因此您需要使用 setViewport 进行一些裁剪,并且最好在窗格的高度或宽度时进行裁剪改变。
你需要做的是计算出图片的比例,并与窗格的比例进行比较,比较会让你决定是否保持图片的原始宽度或原始高度,而你'将使用窗格的比率计算另一个。
不太确定这是否是最佳做法,但这是我所描述内容的代码
double oldImageWidth = image.getWidth(), oldImageHeight = image.getHeight(); //saving the original image size and ratio
double imageRatio = oldImageWidth / oldImageHeight;
imageViewPrincipal.setImage(image);
ChangeListener<Number> listener = (obs, ov, nv) -> {
double paneWidth = imagePane.getWidth();
double paneHeight = imagePane.getHeight();
double paneRatio = paneWidth / paneHeight; //calculating the new pane's ratio
//after width or height changed
double newImageWidth = oldImageWidth, newImageHeight = oldImageHeight;
if (paneRatio > imageRatio) {
newImageHeight = oldImageWidth / paneRatio;
} else if (paneRatio < imageRatio) {
newImageWidth = oldImageHeight * paneRatio;
}
imageViewPrincipal.setViewport(new Rectangle2D( // The rectangle used to crop
(oldImageWidth - newImageWidth) / 2, (oldImageHeight - newImageHeight) / 2, //MinX and MinY to crop from the center
newImageWidth, newImageHeight) // new width and height
);
imageViewPrincipal.setFitWidth(paneWidth);
};
imagePane.widthProperty().addListener(listener);
imagePane.heightProperty().addListener(listener);
这是它的样子
我的数据库中保存了一张图像,该图像作为字节数组传递给图像,然后加载到图像视图。但是,我无法让它填充 imageView。我使用以下代码:
package com.example.AppPrototipo.ui.tourist;
imports...
@Component
public class ExperienceController {
@FXML
Pane imagePane;
@FXML
ImageView imageViewPrincipal;
private final ExperienceRepository experienceRepository;
public ExperienceController(ExperienceRepository experienceRepository) {
this.experienceRepository = experienceRepository;
}
@FXML
private void initialize(){
Experience experience = experienceRepository.findById(1);
Image image = new Image(new ByteArrayInputStream(experience.getImages().get(0).getImageData()));
imageViewPrincipal.setImage(image);
imageViewPrincipal.fitWidthProperty().bind(imagePane.widthProperty());
imageViewPrincipal.fitHeightProperty().bind(imagePane.heightProperty());
}
}
这是我得到的结果:
期望的结果是图像通过裁剪顶部和底部并保持居中来填充整个宽度(填充黑色边)。有人能帮我吗?
假设您在 ImageView 上将 preserveRatio 属性 设置为 true,并且正如 matt 所述是他的评论,您只需要设置其中之一,例如 fitWidth 和 fitHeight将使用图像比例进行计算。
问题是图像和窗格的比例不匹配,因此您需要使用 setViewport 进行一些裁剪,并且最好在窗格的高度或宽度时进行裁剪改变。
你需要做的是计算出图片的比例,并与窗格的比例进行比较,比较会让你决定是否保持图片的原始宽度或原始高度,而你'将使用窗格的比率计算另一个。
不太确定这是否是最佳做法,但这是我所描述内容的代码
double oldImageWidth = image.getWidth(), oldImageHeight = image.getHeight(); //saving the original image size and ratio
double imageRatio = oldImageWidth / oldImageHeight;
imageViewPrincipal.setImage(image);
ChangeListener<Number> listener = (obs, ov, nv) -> {
double paneWidth = imagePane.getWidth();
double paneHeight = imagePane.getHeight();
double paneRatio = paneWidth / paneHeight; //calculating the new pane's ratio
//after width or height changed
double newImageWidth = oldImageWidth, newImageHeight = oldImageHeight;
if (paneRatio > imageRatio) {
newImageHeight = oldImageWidth / paneRatio;
} else if (paneRatio < imageRatio) {
newImageWidth = oldImageHeight * paneRatio;
}
imageViewPrincipal.setViewport(new Rectangle2D( // The rectangle used to crop
(oldImageWidth - newImageWidth) / 2, (oldImageHeight - newImageHeight) / 2, //MinX and MinY to crop from the center
newImageWidth, newImageHeight) // new width and height
);
imageViewPrincipal.setFitWidth(paneWidth);
};
imagePane.widthProperty().addListener(listener);
imagePane.heightProperty().addListener(listener);
这是它的样子