【问题标题】:Why does drawImage from localStorage not work?为什么 localStorage 中的 drawImage 不起作用?
【发布时间】:2021-01-22 20:04:48
【问题描述】:

使用 TypeScript,但我认为这并不重要。

需要 StackOverflow 新标签:localstorage

如果通过 .drawImage 将 img 标签复制到画布上,它可以正常工作。如果你从 localStorage 保存并加载它,你会得到:

drawImage:参数 1 无法转换为以下任何一种:HTMLImageElement、SVGImageElement、HTMLCanvasElement、HTMLVideoElement、ImageBitmap。

Setup in Fiddle

HTML:

<div id="app">
  <img id="img0" src='https://ir.ebaystatic.com/rs/v/fxxj3ttftm5ltcqnto1o4baovyl.png' height='100' width='100'>
  <canvas id="img1" height='100' width='100' style='border:1px solid #d3d3d3;'></canvas>
  <canvas id="img2" height='100' width='100' style='border:1px solid #d3d3d3;'></canvas>
</div>

JS:

const img = document.querySelector("#img0");
img.setAttribute('crossOrigin','anonymous'); // mark image as safe for toDataURL

document.querySelector("#img0").onload = () => {
  saveImg('img0');
};

function saveImg(srcImgID) {
    // save img0 to local storage
  var imgSrc = document.getElementById(srcImgID);
  localStorage.setItem('someStorageKey', imgSrc);

    // copy img0 => img2
  var canvas2: HTMLCanvasElement = document.getElementById('img2') as HTMLCanvasElement;
  console.log('cavas2: ' + canvas2);
  var ctx2 = canvas2.getContext('2d');
  ctx2.drawImage(imgSrc, 0, 0);

    // load img0
  var img0: HTMLImageElement = localStorage.getItem('someStorageKey') as HTMLImageElement;
  console.log('Image data loaded: ' + img0);

    // copy img0 => img1
  var canvas1: HTMLCanvasElement = document.getElementById('img1') as HTMLCanvasElement;
  console.log('cavas1: ' + canvas1);
  var ctx1 = canvas1.getContext('2d');
  ctx1.drawImage(img0, 0, 0); //error: Argument 1 could not be converted to any of: HTMLImageElement...
}

【问题讨论】:

标签: javascript typescript image canvas drawimage


【解决方案1】:

如果要将整个元素保留在localStorage 中,则必须使用imgSrc.outerHTML

localStorage.setItem('someStorageKey', imgSrc.outerHTML);

然后通过特殊方式获取元素:(DOMParser MDN)SO answer

new DOMParser().parseFromString(localStorage.getItem('someStorageKey') as HTMLImageElement, "text/html").body.childNodes[0];

然后等待图片加载:

img0.onload = () => {
  ctx1.drawImage(img0, 0, 0);
}

出于某种原因,我需要将图像附加到&lt;body&gt; 才能正常工作。如果您也遇到这种情况,您可以立即删除图像(可能是 JSFiddle):

document.body.append(img0);img0.remove();

完整代码:

const img = document.querySelector("#img0");
img.setAttribute('crossOrigin','anonymous'); // mark image as safe for toDataURL

document.querySelector("#img0").onload = () => {
  saveImg('img0');
};

function saveImg(srcImgID) {
    // save img0 to local storage
  var imgSrc = document.getElementById(srcImgID);
  localStorage.setItem('someStorageKey', imgSrc.outerHTML);

    // copy img0 => img2
  var canvas2: HTMLCanvasElement = document.getElementById('img2') as HTMLCanvasElement;
  console.log('cavas2: ' + canvas2);
  var ctx2 = canvas2.getContext('2d');
  ctx2.drawImage(imgSrc, 0, 0);

    // load img0
  var img0: HTMLImageElement = new DOMParser().parseFromString(localStorage.getItem('someStorageKey') as HTMLImageElement, "text/html").body.childNodes[0];
  console.log('Image data loaded: ' + img0);

    // copy img0 => img1
  var canvas1: HTMLCanvasElement = document.getElementById('img1') as HTMLCanvasElement;
  console.log('cavas1: ' + canvas1);
  var ctx1 = canvas1.getContext('2d');
    img0.onload = () => {
    ctx1.drawImage(img0, 0, 0);
  }document.body.append(img0);img0.remove();
}

【讨论】:

    【解决方案2】:

    localStorage.setItem 只接受字符串,所以任何不是字符串的东西都会在保存之前运行 .toString(),查看 MDN localStorage.setItem

    您是否考虑过将 img src 保存到 localStorage 并执行类似的操作来渲染它https://stackoverflow.com/a/4776378/12523447

    【讨论】:

      【解决方案3】:

      而不是img html 元素,您应该存储在localStorage 中,只是它的src 属性。然后您只需要创建一个图像,将其src 设置为存储在localStorage 中的值,然后在加载后将其绘制在canvas 上。像这样:

      function saveImg(srcImgID) {
          // save img0 to local storage
        var img = document.getElementById(srcImgID);
        var imgSrc = img.getAttribute('src');
        
        localStorage.setItem('someStorageKey', imgSrc);
      
          // copy img0 => img2
        var canvas2: HTMLCanvasElement = document.getElementById('img2') as HTMLCanvasElement;
        console.log('cavas2: ' + canvas2);
        var ctx2 = canvas2.getContext('2d');
        ctx2.drawImage(img, 0, 0);
      
        var canvas1: HTMLCanvasElement = document.getElementById('img1') as HTMLCanvasElement;
        console.log('cavas1: ' + canvas1);
        var ctx1 = canvas1.getContext('2d');
        
        // load img0
        var img0Src = localStorage.getItem('someStorageKey') as HTMLImageElement;
        var img0 = new Image(); 
        
        img0.src = img0Src;
        
        img0.onload = function () {
          ctx1.drawImage(img0, 0, 0);
        }
      }
       
      

      【讨论】:

      【解决方案4】:

      至少在 JSFiddle 中找到了一个可行的解决方案:https://jsfiddle.net/Dustin_00/nb1j3fw0/70/

      @Rojo 的解决方案同样有效。但在我的 .NET Core 应用程序中都不起作用——只是一个空白图像。

      <div id="app">
        <img id="img0" src='https://ir.ebaystatic.com/rs/v/fxxj3ttftm5ltcqnto1o4baovyl.png' height='100' width='100'>
        <canvas id="canvas1" height='100' width='100' style='border:2px solid #00f;'></canvas>
        <canvas id="canvas2" height='100' width='100' style='border:2px solid #f00;'></canvas>
      </div>
      

      打字稿:

      const img = document.querySelector("#img0");
      img.setAttribute('crossOrigin','anonymous'); // mark image as safe for toDataURL
      
      document.querySelector("#img0").onload = () => {
        saveImg('img0');
      };
      
      function getBase64Image(img) {
        var canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
      
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);
      
        var dataURL = canvas.toDataURL("image/png");
      
        return dataURL;
      }
      
      function saveImg(srcImgID) {
          // save img0 to local storage
        var imgSrc = document.getElementById(srcImgID);
        var imgBase64 = getBase64Image(imgSrc);
        localStorage.setItem('someStorageKey', imgBase64);
      
          // copy img0 => canvas2 (red border)
        var canvas2: HTMLCanvasElement = document.getElementById('canvas2') as HTMLCanvasElement;
        //console.log('cavas2: ' + canvas2);
        var ctx2 = canvas2.getContext('2d');
        ctx2.drawImage(imgSrc, 0, 0);
      
        // load img0
        var imgData = localStorage.getItem('someStorageKey');
      
        // copy img0 => canvas1 (blue border) from storage
        var canvas1: HTMLCanvasElement = document.getElementById('canvas1') as HTMLCanvasElement;
        //console.log('cavas1: ' + canvas1);
        var ctx1 : HTMLCanvasElement = canvas1.getContext('2d');
        //console.log('ctx1: ' + ctx1);
        
        var imgFromStorage = new Image(); 
        imgFromStorage.onload = function () {
          //console.log('imgFromStorage: ' + imgFromStorage);
          //console.log('imgFromStorage.src: ' + imgFromStorage.src);
          ctx1.drawImage(imgFromStorage, 0, 0);
        }
          imgFromStorage.src = imgData;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-10
        • 2014-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-23
        相关资源
        最近更新 更多