首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaFX -防止缩放画布上像素化缩放的模糊

JavaFX -防止缩放画布上像素化缩放的模糊
EN

Stack Overflow用户
提问于 2021-12-18 21:44:57
回答 2查看 255关注 0票数 3

在缩放画布时,有什么方法可以阻止这种模糊吗?我想这和GPU内插有关。但我需要的是一个像素完美的“像素化”放大这里。只需使用最近的“真实”相邻像素的颜色。

我已经看到了这里的解决方案,但在这两种解决方案中(#1 / #4),#4肯定是CPU扩展,#1我猜也是。

这种缩放需要快速-我希望能够支持多达20-25层(可能在一个StackPane画布,但我是开放的其他想法,只要他们不融化CPU)。我怀疑没有JFX提供的GPU支持就能做到这一点,但可能没有足够灵活的API。依赖CPU重标的链接答案中的第4种策略可能行不通。

如果使用此代码放大到最高缩放级别,则模糊是显而易见的。

我们是否需要对JFX进行更新以支持这个或其他什么?这应该是可能的。

代码语言:javascript
运行
复制
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;

public class ScaleTest extends Application {
    
    private static final int width = 1200;
    private static final int height = 800;
    private static final int topMargin = 32;
    private StackPane stackPane;
    private IntegerProperty zoomLevel = new SimpleIntegerProperty(100);
    
    @Override
    public void start(Stage stage) {
        stage.setWidth(width);
        stage.setMinHeight(height);
        
        stackPane = new StackPane();
        stackPane.setLayoutY(topMargin);
        Canvas canvas = new Canvas(width, height - topMargin);
        
        Label label = new Label();
        label.setLayoutY(2);
        label.setLayoutX(2);
        label.setStyle("-fx-text-fill: #FFFFFF");
        label.textProperty().bind(zoomLevel.asString());
        Button zoomInBtn = new Button("Zoom In");
        zoomInBtn.setLayoutY(2);
        zoomInBtn.setLayoutX(50);
        zoomInBtn.onActionProperty().set((e) -> {
            if (zoomLevel.get() < 3200) {
                zoomLevel.set(zoomLevel.get() * 2);
                stackPane.setScaleX(zoomLevel.get() / 100.0);
                stackPane.setScaleY(zoomLevel.get() / 100.0);
            }
        });
        Button zoomOutBtn = new Button("Zoom Out");
        zoomOutBtn.setLayoutY(2);
        zoomOutBtn.setLayoutX(140);
        zoomOutBtn.onActionProperty().set((e) -> {
            if (zoomLevel.get() > 25) {
                zoomLevel.set(zoomLevel.get() / 2);
                stackPane.setScaleX(zoomLevel.get() / 100.0);
                stackPane.setScaleY(zoomLevel.get() / 100.0);
            }
        });
        
        Pane mainPane = new Pane(stackPane, label, zoomInBtn, zoomOutBtn);
        mainPane.setStyle("-fx-background-color: #000000");
        Scene scene = new Scene(mainPane);
        stage.setScene(scene);
        
        drawGrid(canvas, 0, 0, width, height - topMargin, 16);
        stackPane.getChildren().add(canvas);
        
        stage.show();
    }
    
    private void drawGrid(Canvas canvas, int xPos, int yPos, int width, int height, int gridSize) {
        boolean darkX = true;
        String darkCol = "#111111";
        String lightCol = "#222266";
        
        for (int x = xPos; x < canvas.getWidth(); x += gridSize) {
            boolean dark = darkX;
            darkX = !darkX;
            if (x > width) {
                break;
            }
            
            for (int y = yPos; y < canvas.getHeight(); y += gridSize) {
                if (y > height) {
                    break;
                }
                
                dark = !dark;
                String color;
                if (dark) {
                    color = darkCol;
                } else {
                    color = lightCol;
                }
                canvas.getGraphicsContext2D().setFill(Paint.valueOf(color));
                canvas.getGraphicsContext2D().fillRect(x, y, gridSize, gridSize);
            }
        }
    }
}

EN

Stack Overflow用户

发布于 2021-12-19 00:41:59

您的示例将节点的缩放属性调整为重采样 (一个固定大小的映像),这不可避免地会导致这样的伪影。只有向量表示可以以任意精度缩放。您可能需要决定应用程序如何支持向量和/或位图。例如,如果您的应用程序确实是关于缩放矩形的,那么您将调用具有缩放坐标的fillRect(),而不是缩放较小矩形的图片。

您引用了一个很好的总结或调整大小,所以我将重点介绍向量机会:

  • 实际上,Shape的具体子类是可以以任意比例呈现的几何元素的矢量表示;调整这里这里所示示例的大小以查看效果;滚动以缩放和单击以拖动圆圈这里,注意其边界在所有尺度上都保持尖锐。
  • SVGPath是一个可以按这里所示进行缩放的Shape
  • 在内部,Font存储单个象形文字的矢量表示。当实例化时,字形在某一点大小时是光栅化
  • 如果已知合适的向量表示,绘图可以与Canvas的大小绑定,如这里所示。
票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70407385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档