【问题标题】:Adding color-dodge/divide blending mode in fabric.js在fabric.js中添加颜色道奇/划分混合模式
【发布时间】:2019-03-02 16:53:05
【问题描述】:

尝试为color-dodge(或divide两者都非常相似)创建一个新的混合模式选项。

webgl 的当前混合模式列表:

fragmentSource: {
  multiply: 'gl_FragColor.rgb *= uColor.rgb;\n',
  screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n',
  add: 'gl_FragColor.rgb += uColor.rgb;\n',
  diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n',
  subtract: 'gl_FragColor.rgb -= uColor.rgb;\n',
  lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n',
  darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n',
  exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n',
  overlay: 'if (uColor.r < 0.5) {\n' +
      'gl_FragColor.r *= 2.0 * uColor.r;\n' +
    '} else {\n' +
      'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n' +
    '}\n' +
    'if (uColor.g < 0.5) {\n' +
      'gl_FragColor.g *= 2.0 * uColor.g;\n' +
    '} else {\n' +
      'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n' +
    '}\n' +
    'if (uColor.b < 0.5) {\n' +
      'gl_FragColor.b *= 2.0 * uColor.b;\n' +
    '} else {\n' +
      'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n' +
    '}\n',
  tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\n' +
    'gl_FragColor.rgb += uColor.rgb;\n',
},

根据我读过的资源(123),对于color-dodge,数学应该是每个频道并且应该是min(1.0, baseColor / (1 - blendColor))

我已尝试为

添加一个选项
divide: 'gl_FragColor.r = min(1.0, gl_FragColor.r / (1 - uColor.r));\n' +
        'gl_FragColor.g = min(1.0, gl_FragColor.g / (1 - uColor.g));\n' +
        'gl_FragColor.b = min(1.0, gl_FragColor.b / (1 - uColor.b));\n',

但无论传入什么颜色进行混合,结果图像始终是相同蓝色的不同阴影

这是我如何应用过滤器

var fabricImg = new fabric.Image(pageBackgroundImg), // make a fabric.Image object out of the HTMLImageElement
    blendedCanvas = new fabric.StaticCanvas(null, {
        width: fabricImg.getScaledWidth(),
        height: fabricImg.getScaledHeight(),
        renderOnAddRemove: false
    }),
    pageBackgroundPattern;

// add the color filter to the image
fabricImg.filters.push(
    new fabric.Image.filters.BlendColor({
        color: '#' + color,
        mode: 'divide'
    })
);
fabricImg.applyFilters();
// add the image to the canvas
blendedCanvas.add(fabricImg);

blendedCanvas.renderAll();

【问题讨论】:

  • 滤镜会以某种方式改变图像还是根本不改变?
  • 我也确信如果存在向量 min,你可以通过一些向量数学获得相同的效果。
  • 代码看起来不错,我希望它可以工作

标签: javascript canvas html5-canvas webgl fabricjs


【解决方案1】:

所以我添加了一个 sn-p 以便我们更好地理解。 您添加的过滤器正在做某事,如果这是使用 Photoshop 分割/颜色减淡应该发生的情况,我们只能通过比较来理解。 您的代码是正确的,并且确实有效

向下滚动以将原始图像与过滤后的图像进行比较

function start() {
  var canvas = new fabric.Canvas('c');
  var image = document.getElementById('img');
  var fabricImg = new fabric.Image(image); 

  fabric.Image.filters.BlendColor.prototype.fragmentSource.divide =
  'gl_FragColor.r = min(1.0, gl_FragColor.r / (1.0 - uColor.r));\n' +
          'gl_FragColor.g = min(1.0, gl_FragColor.g / (1.0 - uColor.g));\n' +
          'gl_FragColor.b = min(1.0, gl_FragColor.b / (1.0 - uColor.b));\n';
  fabricImg.filters.push(
      new fabric.Image.filters.BlendColor({
          color: '#0000ff',
          mode: 'divide'
      })
  );
  fabricImg.applyFilters();
  canvas.add(fabricImg);
  canvas.requestRenderAll();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.min.js"></script>
<canvas id="c" width=500 height=400 ></canvas>
<img crossOrigin="anonymous" onload="start()" src="https://raw.githubusercontent.com/fabricjs/fabricjs.com/gh-pages/assets/dragon2.jpg" id="img" />

【讨论】:

  • 嗨,感谢您抽出宝贵的时间来研究这个问题。我认为我的问题是我试图混合颜色的图像。但你是对的,那个过滤器确实有效。
  • 你应该打开一个小公关给fabricjs,为它贡献webgl和canvas的代码。
猜你喜欢
  • 2016-01-24
  • 2020-12-25
  • 1970-01-01
  • 2011-11-14
  • 2013-11-14
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
相关资源
最近更新 更多