You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何缩放CustomPainter实现像素风格无抗锯齿显示效果?

Flutter CustomPainter 缩放保留像素风锐利效果方案

问题原因

直接对Canvas调用scale、或者用Transform.scale包裹组件时,Flutter默认使用双线性插值对绘制内容做平滑缩放,仅关闭Paint的抗锯齿无法影响缩放阶段的采样逻辑,因此会出现边缘模糊的问题,和像素风的显示要求不符。

可用解决方案

方案1:全参数缩放绘制(轻量场景首选)

不调用Canvas的scale方法,直接将所有绘制参数统一乘以scaleFactor,完全避开缩放插值流程:

class MyCustomPainter extends CustomPainter{
  final double scaleFactor;
  final int originalWidth = 16;
  final int originalHeight = 16;
  MyCustomPainter(this.scaleFactor);

  @override
  void paint(Canvas canvas, Size size) {
    // 直接绘制缩放后的内容,不调用canvas.scale
    canvas.drawPaint(Paint()..color = Colors.white70);
    canvas.drawLine(
      Offset(4*scaleFactor,4*scaleFactor), 
      Offset(12*scaleFactor,12*scaleFactor), 
      Paint()
        ..color = Colors.black
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1*scaleFactor // 线宽同步缩放
        ..isAntiAlias = false // 关闭抗锯齿
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

外层布局不需要调整,保持原有写法即可。该方案性能开销最低,适合绘制逻辑简单、绘制元素少的场景。


方案2:离屏渲染后硬缩放(复杂场景首选)

如果绘制逻辑复杂,逐一修改所有绘制参数成本太高,可以先把原始像素尺寸的内容绘制到离屏画布,生成图像后再以最近邻采样的方式缩放到目标尺寸,核心是给绘制图像的Paint设置filterQuality: FilterQuality.none,该参数会指定缩放时不做平滑插值,直接取最近像素点:

import 'dart:ui' as ui;

class MyCustomPainter extends CustomPainter{
  final double scaleFactor;
  final ui.Image originalImage; // 提前生成的原始16x16尺寸图像
  MyCustomPainter(this.scaleFactor, this.originalImage);

  @override
  void paint(Canvas canvas, Size size) {
    // 将原始图像缩放到目标尺寸,使用最近邻采样
    canvas.drawImageRect(
      originalImage,
      Rect.fromLTWH(0, 0, originalImage.width.toDouble(), originalImage.height.toDouble()),
      Rect.fromLTWH(0, 0, 16*scaleFactor, 16*scaleFactor),
      Paint()
        ..filterQuality = FilterQuality.none // 核心参数,关闭插值
        ..isAntiAlias = false
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

注意:CustomPainter的paint方法不支持异步操作,原始尺寸图像的生成逻辑(PictureRecorder录制、toImage异步转换)需要提前在State层的initState等生命周期中完成,再将生成的图像传入Painter使用。

该方案可以保留原有的原始尺寸绘制逻辑,不需要修改任何绘制参数,仅需要增加离屏渲染和缩放绘制的逻辑,适合绘制元素多、逻辑复杂的场景。

内容的提问来源于stack exchange,提问作者Gustavo Guzman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:36:04