【问题标题】:In Flutter, is it possible to draw an image with a replaced color and opacity?在 Flutter 中,是否可以用替换的颜色和不透明度绘制图像?
【发布时间】:2022-01-23 17:16:34
【问题描述】:

我有一张灰色的图像。我想用一种颜色来绘制它,但对画布不透明。通过使用滤色器,我可以通过替换颜色在画布上绘制它。如果我调整 alpha 值,它会改变图像的不透明度(部分灰色/红色)。以下代码 sn-p 显示了如何在画布上绘制灰色图像为红色。但是如何将红色图像绘制为对画布透明?

static void drawBrushDetail(Canvas canvas, double cx, double cy, double brushSize, double imageAngleRad) {
    canvas.translate(cx + brushSize / 2, cy + brushSize / 2);
    ui.Image bt = imgBrushTip; //this is a gray image
    Color selectedColor = getDrawColor(cx,cy);
    final _paint = Paint();
    var alphaVal=255;
    //if I change alphaVal to 100, the final draw looks more gray instead of red with 100 Alpha
    _paint.colorFilter = ColorFilter.mode(selectedColor.withAlpha(alphaVal), BlendMode.srcATop);
    if (imageAngleRad != 0.0) canvas.rotate(imageAngleRad);
    canvas.translate(-brushSize / 2, -brushSize / 2);
    
    // draw image with specified brushSize
    canvas.drawImageRect(bx, Rect.fromLTRB(0, 0, bt.width, bt.height),
        Rect.fromLTRB(0, 0, brushSize, brushSize), _paint);
    //traslate back, don't want to use save and restore layer since it's expensive
    canvas.translate(brushSize / 2, brushSize / 2);
    if (imageAngleRad != 0.0) canvas.rotate(-imageAngleRad);
    canvas.translate(-cx - brushSize / 2, -cy - brushSize / 2);
}

见下图。上面的代码将用纯红色绘制图像。 (红色箭头指向的图像)。但我希望结果是红色和透明的图像。由于在Flutter中没有设置canvas alpha的API,不知道是否可以。

【问题讨论】:

  • @pskink 感谢您的评论。我添加了图片以澄清问题。
  • final p0 = Paint()..colorFilter = ColorFilter.mode(Colors.white.withOpacity(0.75), BlendMode.dstIn); final p1 = Paint()..colorFilter = ColorFilter.mode(Colors.orange, BlendMode.modulate); canvas ..saveLayer(Offset.zero & imageSize, p0) ..drawImage(image, Offset.zero, p1) ..restore(); - 除了modulate,你也可以使用srcATop 或其他模式
  • 你也可以使用:final matrix = Matrix4.translationValues(100.0, 250.0, 0).storage; final p2 = Paint() ..colorFilter = ColorFilter.mode(Colors.orange.withOpacity(0.75), BlendMode.srcIn) ..shader = ImageShader(image!, TileMode.decal, TileMode.decal, matrix); canvas.drawPaint(p2);
  • @pskink,这超出了我的理解。我会玩弄它,看看我能不能弄明白。
  • 什么是无法理解的?请注意,第一个解决方案可能很昂贵(对于更大的图像),因为使用了 Canvas.saveLayer

标签: flutter image canvas filter


【解决方案1】:

我想通了,但功劳归于pskink

我只需要绘制一张图像(灰色),但我需要执行以下操作:

  1. 调整图像大小并旋转图像。
  2. 用红色替换灰色图像。
  3. 使用不透明度绘制图像(现在为红色)。

这里是代码sn-p。

static void drawBrushDetail1(Canvas canvas, double cx, double cy, double size) {
    final _paint = Paint();
    const opacity = 0.5;
    _paint.color = Color.fromRGBO(0, 0, 0, opacity);
    ui.Image bx = uiImg[0];
    double scale = size / 60; //size is brush tip size and 60x60 is gray image size
    canvas.drawAtlas(
        bx,
        [
             RSTransform.fromComponents(
              rotation: imageAngleRad,
              scale: scale,
              anchorX: 30,
              anchorY: 30,
              translateX: cx,
              translateY: cy)
        ],
        [
          /* The size of gray image is 60 x 60  */
          const Rect.fromLTWH(0, 0, 60, 60)
        ],
        [Colors.red],
        BlendMode.dstIn, /*This is replace the gray image wiht red color
        null /* No need for cullRect */,
        _paint); //_paint will paint the red image in 0.5 opacity
    
  }

【讨论】:

  • 我同意。我需要更多地使用它来更好地了解它的潜力。您提供的示例代码非常好。我希望 Flutter 拥有的唯一另一件事是可以在其上绘制的缓冲图像,类似于 Java2D,但那将是一个不同的主题。
猜你喜欢
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2014-05-08
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 2012-05-07
相关资源
最近更新 更多