简体   繁体   English

如何使用 Javascript CANVAS API 将图像转换为类似草图的图像

[英]how to Convert Image to Sketch-like-image using Javascript CANVAS API

Hi so I'm trying to convert an image to sketch-like-image before uploading it to the server, the uploading part is not the problem, the conversion of image to sketch-like-image is.您好,我正在尝试在将图像上传到服务器之前将其转换为类似草图的图像,上传部分不是问题,将图像转换为类似草图的图像才是问题。 I failed to search a js library that will help me achieve this, and then I found this https://www.freecodecamp.org/news/sketchify-turn-any-image-into-a-pencil-sketch-with-10-lines-of-code-cf67fa4f68ce sample code in python then tried to recreate it using CSS only and I got it correctly using the CSS code below我没有搜索到可以帮助我实现此目的的 js 库,然后我找到了这个https://www.freecodecamp.org/news/sketchify-turn-any-image-into-a-pencil-sketch-with-10 -lines-of-code-cf67fa4f68ce python 中的python代码然后尝试仅使用 CSS 重新创建它,我使用下面的 CSS 代码正确地获得了它

filter: grayscale(100%) invert(100%) blur(5px);
mix-blend-mode: color-dodge;

Then after that I tried to recreate it in Vanilla Javascript using CANVAS API because I needed the image to be uploaded in the server that looks like a sketch-like-image, but got stuck in the process here are the stages of the conversion I'm doing see image below然后我尝试使用 CANVAS API 在 Vanilla Javascript 中重新创建它,因为我需要将图像上传到服务器中,看起来像草图一样的图像,但卡在这个过程中是转换的阶段我'我正在看下面的图片在此处输入图像描述

I got stuck in the stage 4, I can't proceed with the stage 5, which is globalCompositeOperation = 'color-dodge';我卡在第4阶段,无法进行第5阶段,也就是globalCompositeOperation = 'color-dodge'; when color-dodge applied to CANVAS API, to remove the blur and make it look like an sketch-image当颜色减淡应用于 CANVAS API 时,去除模糊并使其看起来像草图图像

  • stage 1 is the raw image阶段 1 是原始图像
  • stage 2 is grayscale(100%) working in javascript CANVAS API第 2 阶段是grayscale(100%)工作在 javascript CANVAS API
  • stage 3 is invert(100%) working in javascript CANVAS API第 3 阶段是invert(100%)工作在 javascript CANVAS API
  • stage 4 is blur(5px) working in javascript CANVAS API第 4 阶段是blur(5px)在 javascript CANVAS API 中工作
  • stage 5 globalCompositeOperation = 'color-dodge' which is equivalent of CSS' mix-blend-mode: color-dodge;阶段 5 globalCompositeOperation = 'color-dodge'相当于 CSS' mix-blend-mode: color-dodge; I think?我认为? I'm not sure but I assumed it is.我不确定,但我认为是。 not working in javascript CANVAS API不工作javascript CANVAS API

and here's my Javascript code below下面是我的 Javascript 代码

  let img = document.createElement('img');
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext('2d');
  ctx.filter = 'grayscale(100%) invert(100%) blur(5px)'; // stages 2,3,4 is working
  ctx.globalCompositeOperation = 'color-dodge'; // stage 5 not working
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

Ok so I think that's a lot so here's a snippet of it for you guys to test it out.好的,所以我认为这很多,所以这里有一个片段供你们测试。 https://codepen.io/ohyeahhu/pen/MWQRweP https://codepen.io/ohyeahhu/pen/MWQRweP

also if you guys know a JS library or tools that might help me achieve this feat, I'm very open to any suggestions.另外,如果你们知道可以帮助我实现这一壮举的 JS 库或工具,我非常愿意接受任何建议。

note: only in javascript or any js library注意:仅在 javascript 或任何 js 库中

Posting it here for others, the solution to this is I need to generate a black & white and blur canvas/img separately and then merge them using CANVAS API.在这里发布给其他人,解决方案是我需要分别生成黑白和模糊画布/img,然后使用 CANVAS API 合并它们。

So to summarize the code below, I created 2 function. filter and generateSketch , filter purpose is to add filter to the canvas element and generateSketch is to merge two canvas (black & white and blur) into one to create a sketch like image.所以总结下面的代码,我创建了 2 function.filter 和generateSketchfilter的目的是为 canvas 元素添加filter ,而generateSketch是将两个 canvas(黑白和模糊)合并为一个,以创建类似图像的草图。

HTML HTML

    <div class="col-sm-6">
      <h1 class="text-center">Converted using JAVASCRIPT</h1>
      <div class="row">
        <div class="col-sm-6">
          <img src="https://i.postimg.cc/Wb5CcD8L/corgi2.jpg" id="raw-img" class="d-block w-100">
        </div>
        <div class="col-sm-6" id="result">
        </div>
      </div>
    </div>

Javascript Javascript

  window.addEventListener('DOMContentLoaded', async (event) => {
    // add filters to canvas element
    const filter = (bmp, filters="") => {
      let canvas = Object.assign(document.createElement('canvas'), { width: bmp.width, height: bmp.height });
      let ctx = canvas.getContext('2d');
      ctx.filter = filters;
      ctx.drawImage(bmp, 0, 0);
      return canvas;
    }
    // merge two canvas into one to generate sketch like image
    const generateSketch = (bnw, blur) => {
      let canvas = document.createElement('canvas');
      canvas.width = bnw.width;
      canvas.height = bnw.height;
      canvas.__skipFilterPatch = true; // davidenke/context-filter-polyfill fix for safari ios devices
      let ctx = canvas.getContext('2d');
      ctx.drawImage(bnw, 0, 0, canvas.width, canvas.height);
      ctx.globalCompositeOperation = 'color-dodge';
      ctx.drawImage(blur, 0, 0, canvas.width, canvas.height);
      return canvas;
    }
    let rawImg = document.getElementById('raw-img');
    // first: step create bitmap from the `rawImg`
    let bmp = await createImageBitmap(rawImg);
    // second: generate a black & white and blur canvas using filter()
    let bnw = filter(bmp, "grayscale(1)");
    let blur = filter(bmp, "grayscale(1) invert(1) blur(5px)");
    // third: merge / combine `bnw` and `blur` canvas
    let sketchImg = generateSketch(bnw, blur);
    // display output
    let resultDiv = document.getElementById('result');
    resultDiv.prepend(sketchImg);
  });

you can check it on my codepen for the working sample https://codepen.io/ohyeahhu/pen/MWQRweP .您可以在我的代码笔上查看工作示例https://codepen.io/ohyeahhu/pen/MWQRweP

note: I also used https://github.com/davidenke/context-filter-polyfill to fix the compatibility issue on Safari IOS devices.注意:我还使用https://github.com/davidenke/context-filter-polyfill来修复 Safari IOS 设备上的兼容性问题。

This is also related to this CanvasRenderingContext2D.globalCompositeOperation is not working on safari这也和这个CanvasRenderingContext2D.globalCompositeOperation is not working on safari有关

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM