Flutter - 如何将图像与渐变颜色混合?

Posted

技术标签:

【中文标题】Flutter - 如何将图像与渐变颜色混合?【英文标题】:Flutter - How to blend an image with a gradient colour? 【发布时间】:2018-12-13 21:32:39 【问题描述】:

我正在尝试复制我的设计师为应用所做的登录屏幕设计。

背景图像使用 softLight 的 blendMode,关键是它混合的颜色是渐变色。其次其实有两层不同的渐变(一层紫色渐变,一层蓝色渐变)

原图:

最终渐变图像

现在我已经尝试使用 colorBlendMode,例如

Image.asset(
      'assets/pioneer-party.jpg',
      fit: BoxFit.cover,
      color: Color(0xff0d69ff).withOpacity(1.0),
      colorBlendMode: BlendMode.softLight,
    ),

问题在于 color 属性只采用一种颜色。

然后我尝试了 BoxDecoration,例如

DecoratedBox(
      decoration: new BoxDecoration(
        color: const Color(0xff7c94b6),
        image: new DecorationImage(
          fit: BoxFit.cover,
          colorFilter: new ColorFilter.mode(Colors.purple.withOpacity(1.0), BlendMode.softLight),
          image: new NetworkImage(
            'http://www.allwhitebackground.com/images/2/2582-190x190.jpg',
          ),
        ),
      ),
    ),

这仍然让我遇到同样的问题。然后我尝试单独堆叠每一层,然后使用渐变来使其看起来接近设计,例如

Image.asset(
      'assets/pioneer-party.jpg',
      fit: BoxFit.cover,
      color: Color(0xff0d69ff).withOpacity(1.0),
      colorBlendMode: BlendMode.softLight,
    ),
    DecoratedBox(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: FractionalOffset.topCenter,
          end: FractionalOffset.bottomCenter,
          colors: [
            Color(0xff0d69ff).withOpacity(0.0),
            Color(0xff0069ff).withOpacity(0.8),
          ],
        ),
      ),
    ),
    DecoratedBox(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: FractionalOffset.topLeft,
          end: FractionalOffset.bottomRight,
          colors: [
            Color(0xff692eff).withOpacity(0.8),
            Color(0xff642cf4).withOpacity(0.8),
            Color(0xff602ae9).withOpacity(0.8),
            Color(0xff5224c8).withOpacity(0.8),
            Color(0xff5e29e5).withOpacity(0.8),
          ],
        stops: [0.0,0.25,0.5,0.75,1.0]
        ),
      ),
    ),

这让我有点接近我想要的,但不完全是我需要的。

有谁知道实现这一目标的方法吗?

编辑:

我也在考虑将这两个图像混合在一起,但除了使用不透明度或其他东西之外,还没有找到这样做的方法。理想情况下希望它以原生方式呈现,而不是使用“hacks”来实现它。

【问题讨论】:

我目前无法写出完整的答案,但我建议您考虑使用 CustomPaint 和画布。使用画布,您可以根据自己的喜好绘制渐变和图像,然后在合并图层时应用过滤器。这将是一个昂贵的平局,但如果一切都是静态的,应该没问题。如果你有东西在移动,那么也许我可以在某个时候重新评估。但是话又说回来 - 如果图像是静态的,为什么不先在 Photoshop 中合并它并使用最终图像 =D。 嗨@rmtmckenzie 感谢您的意见。图像将是静态的,但我们希望在整个应用程序中使用此效果,因此在不同的地方将应用相同的效果,但将使用不同的背景图像。否则是的,我肯定宁愿使用 Photoshop 图像并完成它哈哈。 好的,那么您应该能够使用 CustomPaint 做您想做的事情。一旦你弄清楚了它所需的样板的语义,Canvas 本身的行为就很像其他语言中的 Canvas,所以如果你熟悉它们,你应该能够弄清楚。如果没有,这就是我们来这里的目的! 这里是答案:***.com/questions/55102880/… 【参考方案1】:

使用堆栈来获得这个效果非常简单。

   Stack(children: <Widget>[
        Container(
          decoration: BoxDecoration(
            color: Colors.transparent,
            image: DecorationImage(
              fit: BoxFit.fill,
              image: AssetImage(
                'images/bg.jpg',
              ),
            ),
          ),
          height: 350.0,
        ),
        Container(
          height: 350.0,
          decoration: BoxDecoration(
              color: Colors.white,
              gradient: LinearGradient(
                  begin: FractionalOffset.topCenter,
                  end: FractionalOffset.bottomCenter,
                  colors: [
                    Colors.grey.withOpacity(0.0),
                    Colors.black,
                  ],
                  stops: [
                    0.0,
                    1.0
                  ])),
        )
      ]),  

干杯

【讨论】:

优秀。我尝试使用 ShaderMask 来获得相同的结果,但似乎 ShaderMask 仍然有一些意外行为(例如参见 ***.com/questions/61396798/…)。这个解决方案似乎是迄今为止我见过的在图像上应用渐变滤镜的最佳解决方案。 我也一直在寻找这个解决方案,它适用于“图像+渐变色”合成。【参考方案2】:

你也可以试试这个:

ColorFiltered(
  colorFilter: ColorFilter.mode(Colors.red.withOpacity(0.4), BlendMode.srcOver),
  child: YourWidget(),
) 

【讨论】:

但这不会添加渐变,您只能将图像与单一颜色混合 @maheshmnj 你可以尝试嵌套ColorFiltered 并使YourWidget 成为最后一个ColorFilteredchild 我试过 colorFilter 但它会降低图像质量。有没有其他办法。【参考方案3】:

我的解决方案是用 shaderMask 包裹我的图像,这是一个对我有用的示例

ShaderMask(
  shaderCallback: (bounds) 
    return LinearGradient(
      colors: node.badge!.colorsArray,
    ).createShader(bounds);
  ,
  child: Image.asset(
    Assets.main_logo,
    height: 27.0,
    fit: BoxFit.cover,
  ),
  blendMode: BlendMode.srcATop,
),

如果您参考 BlendMode 文档https://docs.flutter.io/flutter/dart-ui/BlendMode-class.html,您实际上可以找到您需要的内容

【讨论】:

以上是关于Flutter - 如何将图像与渐变颜色混合?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 2 个图像与 PHP(GD-GD2 库)混合,如乘法、颜色燃烧、颜色道奇等

混合模式 kCGBlendModeMultiply 未正确地将图像与颜色相乘

Flutter InkWell 小部件未通过容器的渐变和颜色显示

如何向 React Native 应用程序添加启动画面(图像或渐变颜色)

Flutter 颜色渐变及模仿淘宝渐变关注按钮

为uibutton背景图像iphone sdk设置渐变颜色(颜色)