JavaFX ImageView没有任何平滑

ajs*_*vig 15 javafx javafx-2

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

但是,生成的渲染仍然可以平滑所有16个目标像素上的源像素.有没有人知道如何在不手动将每个像素复制到新图像的情况下执行此操作?

jew*_*sea 25

在JavaFX 2.2 ImageView中总是会做一些平滑,无论你提供的平滑提示如何ImageView.

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

也许这是一个ImageView总是能够平滑的错误Image,但是文档并没有真正指定平滑做什么或不做什么,所以很难说它的真正意图是什么.您可能希望将此问题的引用发布到openjfx-dev邮件列表,或者在JavaFX问题跟踪器中记录问题以获得开发人员的更专家意见.


我尝试了一些不同的方法来缩放图像:

  1. Image构造函数中缩放.
  2. 规模ImageViewfitWidth/fitHeight.
  3. 使用scaleX/scaleY属性进行缩放ImageView.
  4. 通过Image使用PixelReader进行采样并使用PixelWriter创建新图像进行缩放.

我发现方法1和4导致了一个像素图像的锐利像素,而2和3导致模糊的混叠图像.

机器人采样

用于生成上述输出的示例代码.


更新有关实施您自己的图像过滤器的想法

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

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

您可能还希望针对JavaFX运行时项目提交功能请求,以"允许我们创建自己的2D过滤器".

  • 这个答案已经过去两年了.有谁知道这是否已在JavaFX中修复? (2认同)

Mar*_*jka 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);
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的技巧是重新使用纹理,因此线性过滤设置保持“粘性”。NGImageView然而,为什么不能简单地将“平滑”标志传递给纹理的线性过滤设置是我无法理解的。

  • 这适用于 Java 8,但看起来这里提到的函数已在 Java 9 中重命名并设置为私有函数。如果不对 `ImageView` 和 `ImageViewHelper` 进行重大更改,它看起来不能以相同的方式覆盖。有人想出如何解决 Java 9 中的新限制吗? (2认同)