是否可以在 JavaFX 2.2 的 ImageView 中呈现缩放图像而不应用任何平滑?我正在使用 setSmooth(false) 将 50x50 图像渲染为 200x200 ImageView,因此源图像中的每个像素都应映射到屏幕上的 4x4 正方形。
但是,生成的渲染仍然会平滑所有 16 个目标像素的源像素。有谁知道无需手动将每个像素复制到新图像中的方法?
在 JavaFX 2.2中ImageView
,无论您向. ImageView
(基于使用带有 ATI HD4600 显卡的 Java 7u15 和 Windows 7 进行的测试)。
也许这是一个ImageView
总是会平滑Image
. 您可能希望将对此问题的引用发布到openjfx-dev 邮件列表或在JavaFX 问题跟踪器中记录问题,以便从开发人员那里获得更专业的意见。
我尝试了几种不同的方法来缩放图像:
ImageView
使用fitWidth / fitHeight进行缩放。ImageView
Image
使用PixelWriter创建新图像来进行缩放。我发现方法 1 和 4 会产生您想要的清晰的像素化图像,而方法 2 和 3 会产生模糊的混叠图像。
生成上述输出的示例代码。
更新实现自己的图像过滤器的想法
JavaFX 效果与用于图像加载例程的过滤器不同,尽管可以创建过滤图像的效果。在 JavaFX 2.2 中公开记录的 API 支持创建自定义效果,因此创建自定义效果可能会很困难。
图像支持的本机代码最近作为openjfx 项目的一部分开源,因此您可以查看它以了解当前如何实现过滤。
您可能还想针对 JavaFX 运行时项目提交功能请求,以“允许我们制作自己的 2D 过滤器”。
我知道这有点老了,但我最近需要这样的 ImageView,下面的小技巧正是我想要在我的 (Windows) 机器上做的。不能保证它在任何地方都有效。
import com.sun.javafx.sg.prism.NGImageView;
import com.sun.javafx.sg.prism.NGNode;
import com.sun.prism.Graphics;
import com.sun.prism.Texture;
import com.sun.prism.impl.BaseResourceFactory;
import com.sun.prism.Image;
import javafx.scene.image.ImageView;
@SuppressWarnings("restriction")
public class PixelatedImageView extends ImageView {
@Override protected NGNode impl_createPeer() {
return new NGImageView() {
private Image image;
@Override public void setImage(Object img) {
super.setImage(img);
image = (Image) img;
}
@Override protected void renderContent(Graphics g) {
BaseResourceFactory factory = (BaseResourceFactory) g.getResourceFactory();
Texture tex = factory.getCachedTexture(image, Texture.WrapMode.CLAMP_TO_EDGE);
tex.setLinearFiltering(false);
tex.unlock();
super.renderContent(g);
}
};
}
}
这里的技巧是纹理被重新使用,所以线性过滤设置保持“粘性”。但是,为什么NGImageView
不能简单地将“平滑”标志传递给纹理的线性过滤设置,这超出了我的理解。
ImageView 没有修复,但它帮助了我很多。在搜索了很多年之后,我偶然发现了这篇文章:如何在 JavaFX 画布上禁用抗锯齿?
为了在画布上绘制图像,从 JavaFX 12 开始可以禁用平滑
canvas.getGraphicsContext2D().setImageSmoothing(false);
当您将以下构造函数添加到 Martin Sojka 的答案时,您可以简单地将 javafx Image 传递给构造函数。此外,尽管有关于已弃用功能的警告,但他的答案仍然可以正常工作(在 JDK 1.8_121 上)。
public PixelatedImageView (javafx.scene.image.Image image) {
super(image);
}