20

是否可以在 JavaFX 2.2 的 ImageView 中呈现缩放图像而不应用任何平滑?我正在使用 setSmooth(false) 将 50x50 图像渲染为 200x200 ImageView,因此源图像中的每个像素都应映射到屏幕上的 4x4 正方形。

但是,生成的渲染仍然会平滑所有 16 个目标像素的源像素。有谁知道无需手动将每个像素复制到新图像中的方法?

4

4 回答 4

33

在 JavaFX 2.2ImageView,无论您向. ImageView

(基于使用带有 ATI HD4600 显卡的 Java 7u15 和 Windows 7 进行的测试)。

也许这是一个ImageView总是会平滑Image. 您可能希望将对此问题的引用发布到openjfx-dev 邮件列表或在JavaFX 问题跟踪器中记录问题,以便从开发人员那里获得更专业的意见。


我尝试了几种不同的方法来缩放图像:

  1. Image 构造函数中缩放。
  2. ImageView使用fitWidth / fitHeight进行缩放。
  3. 使用. _ _ _ _ImageView
  4. 通过使用 PixelReader 采样并Image使用PixelWriter创建新图像来进行缩放

我发现方法 1 和 4 会产生您想要的清晰的像素化图像,而方法 2 和 3 会产生模糊的混叠图像。

机器人采样

生成上述输出的示例代码。


更新实现自己的图像过滤器的想法

JavaFX 效果与用于图像加载例程的过滤器不同,尽管可以创建过滤图像的效果。在 JavaFX 2.2 中公开记录的 API 支持创建自定义效果,因此创建自定义效果可能会很困难。

图像支持的本机代码最近作为openjfx 项目的一部分开源,因此您可以查看它以了解当前如何实现过滤。

您可能还想针对 JavaFX 运行时项目提交功能请求,以“允许我们制作自己的 2D 过滤器”。

于 2013-04-18T20:38:57.883 回答
6

我知道这有点老了,但我最近需要这样的 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不能简单地将“平滑”标志传递给纹理的线性过滤设置,这超出了我的理解。

于 2016-09-02T14:13:10.040 回答
1

ImageView 没有修复,但它帮助了我很多。在搜索了很多年之后,我偶然发现了这篇文章:如何在 JavaFX 画布上禁用抗锯齿?

为了在画布上绘制图像,从 JavaFX 12 开始可以禁用平滑

canvas.getGraphicsContext2D().setImageSmoothing(false);
于 2021-04-08T18:23:41.090 回答
0

当您将以下构造函数添加到 Martin Sojka 的答案时,您可以简单地将 javafx Image 传递给构造函数。此外,尽管有关于已弃用功能的警告,但他的答案仍然可以正常工作(在 JDK 1.8_121 上)。

public PixelatedImageView (javafx.scene.image.Image image) {
    super(image);
}
于 2017-04-03T18:57:21.320 回答