画布 drawImage img 源与画布源

时间:2021-06-08 11:05:06

标签: javascript canvas html5-canvas

我对相同的图像使用 drawImage 函数,但是当源是 img 元素与源是画布(与原始图像大小相同)时,我得到了不同的结果。

这是代码

  async function draw(src) {

        const mainCanvas = document.getElementById("cnv");
        const ctx = mainCanvas.getContext("2d");
        let img = document.getElementById("img");

        let w = img.width;
        let h = img.height;
        if (src == "cnv") {
         
          const newCnv =      document.createElement("canvas");
          newCnv.width = w;
          newCnv.height = h;

          const newCtx = newCnv.getContext("2d");
          //just to be sure we dont touch the original image data
          newCtx.imageSmoothingEnabled = false;
          // i tested it with all function overloads and still the same
          newCtx.drawImage(img, 0, 0, w, h, 0, 0, w, h);
          img = newCnv;

        }

        let destW = 850;
        const pxr = window.devicePixelRatio;
        let destH = (destW * h) / w;
        mainCanvas.style.width = destW + "px";
        mainCanvas.style.height = destH + "px";

        destW *= pxr;
        destH *= pxr;

        mainCanvas.width = destW;
        mainCanvas.height = destH;

        ctx.imageSmoothingQuality = "high";

        ctx.drawImage(img, 0, 0, destW, destH);
      }
<img
      id="img"
      style="display: none"
      src="https://work.otzar.org/example.png"
    />
<button onclick="draw('img')">drawImage from img</button>
<button onclick="draw('cnv')">drawImage from canvas</button>
<br />
<canvas id="cnv"> </canvas>

我知道当您使用 drawImage 时,它会做一些工作,例如当目标尺寸较小时缩小尺寸。但这里的 newCnv 与原始图像相同,所以我不明白为什么 js 需要做一些事情,而不仅仅是将像素数据放在画布中。

1 个答案:

答案 0 :(得分:1)

罪魁祸首是 read(String key) async { final prefs = await SharedPreferences.getInstance(); Map<String, dynamic> userMap; final String userStr = await prefs.getString("pessoas"); if (userStr != null) { //final Pessoas user = await Pessoas.fromJson(userMap); print(json.decode(userStr)); return json.decode(userStr); } //return null; //return json.decode(prefs.getString(key)); } ,我以前也遇到过,即使使用 ImageBitmaps。
不同的来源使用他们的算法会得到不同的结果,即使是两个 JPEG 也会有很大不同的质量,这取决于图像的压缩程度。

你做得很好opening that issue

请注意,在我的测试中,我使用 imageSmothingQuality = "high" 获得了最好的结果,它也没有受到此错误的影响。

imageSmothingQuality = "medium"
async function draw(src) {

  const mainCanvas = document.getElementById("cnv");
  const ctx = mainCanvas.getContext("2d");
  let img = document.getElementById("img");

  let w = img.width;
  let h = img.height;
  if (src == "cnv") {

    const newCnv =      document.createElement("canvas");
    newCnv.width = w;
    newCnv.height = h;

    const newCtx = newCnv.getContext("2d");
    //just to be sure we dont touch the original image data
    newCtx.imageSmoothingEnabled = false;
    // i tested it with all function overloads and still the same
    newCtx.drawImage(img, 0, 0, w, h, 0, 0, w, h);
    img = newCnv;

  }

  let destW = 850;
  const pxr = window.devicePixelRatio;
  let destH = (destW * h) / w;
  mainCanvas.style.width = destW + "px";
  mainCanvas.style.height = destH + "px";

  destW *= pxr;
  destH *= pxr;

  mainCanvas.width = destW;
  mainCanvas.height = destH;

  ctx.imageSmoothingQuality = "medium";

  ctx.drawImage(img, 0, 0, destW, destH);
}