如何在JavaFX的画布上禁用drawImage的线性过滤

3

我正在尝试在JavaFX的画布上绘制缩放后的图像。使用以下代码:

Image image = ...;
canvas.setWidth(scale * width);
canvas.setHeight(scale * height);
GraphicsContext gc = canvas.getGraphicsContext2D();    
gc.drawImage(image, 0, 0, scale * width, scale * height);
// this gives same result
// gc.scale(scale, scale);
// gc.drawImage(editableImage, 0, 0, width, height);

它工作速度非常快,但会产生像这样的模糊图像:

enter image description here

这不是我想要看到的。相反,我想要得到这张图片:

enter image description here

可以通过手动设置每个像素的颜色来绘制,使用以下代码:

PixelReader reader = image.getPixelReader();
PixelWriter writer = gc.getPixelWriter();
for (int y = 0; y < scale * height; ++y) {
    for (int x = 0; x < scale * width; ++x) {
        writer.setArgb(x, y, reader.getArgb(x / scale, y / scale));
    }
}

但是我不能使用这种方法,因为它太慢了。将1Kb图像缩放8倍需要几秒钟的时间。所以我想知道是否有任何方法可以在canvas上绘制时禁用这种模糊效果?


相关问题,甚至可能是重复的:https://dev59.com/2mQo5IYBdhLWcg3wZelg - fabian
@fabian,正如您所看到的,这个问题是关于ImageView的。Canvas则完全不同。 - Nolan
1个回答

4

更新于10/07/2019:

看起来这个问题已经解决了!现在GraphicsContext应该有一个控制这种行为的"图像平滑"属性。

初始回答

我想我找到了我的问题的答案。因为这个问题说没有办法在图形上下文中指定过滤选项。

描述:

当使用GraphicsContext中的drawImage()方法将小图像放大到较大画布时,图像会被插值(可能使用双线性或双三次算法)。但是,在渲染色彩映射(温度、浮游生物、盐度等)或某些地理数据(人口集中度等)时,我们希望完全不进行插值(即使用最近邻算法),以表示准确的数据和形状。
在Java2D中,可以通过在Graphics2D上设置适当的RenderingHints.KEY_RENDERING来实现。目前在JavaFX的GraphicsContext上,没有这样的方法来指定如何插值图像。
缩小图像时也是如此。
这可以扩展以支持更好的平滑形式,该形式在Image和ImageView中都可用,但当前似乎效果不佳(至少在Windows上)。
该问题创建于2013年,但仍未解决,因此不太可能很快得到解决。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接