【问题标题】:Can I load a local file into an html canvas element?我可以将本地文件加载到 html 画布元素中吗?
【发布时间】:2022-02-24 19:03:22
【问题描述】:

我的目标是让 iPad 上的用户将图像加载到画布中,然后在 离线

的同时获取 base 64 编码的所述图像

JSFiddle

JSFiddle

代码

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="../js/libs/jquery-1.7.1.min.js"></script>
    <script>
      $(document).ready(function(){ 
        //Get the canvas
        var canvas = document.getElementById('testCanvas');
        var context = canvas.getContext('2d');   

        $("#testButton").click(function(){
          var base_image = new Image();

          base_image.src = $("#testImg").val();
          //base_image.src = '1.jpg';

          //When the image loads
          $(base_image).load(function(){
            //Resize canvas for image
            $("#testCanvas").attr({
              width: base_image.width,
              height: base_image.height
            });

            //Draw image on canvas
            context.drawImage(base_image, 0, 0);

            //Get base64 encoded image
            var imageString = canvas.toDataURL("image/jpeg");
            $("#imageString").val(imageString);

            //alert($("#imageString").val().length);
            $("#imageOutput").attr("src", imageString);
          });//image load
        });//Test Button Click
      });//doc ready
    </script>
  </head>

  <body>
    <form>
      <input type="file" name="testImg" id="testImg" />
    </form>
    <button id="testButton">Test</button>
    <canvas id="testCanvas" style="border: 1px solid black;">Your Browser does not support canvas</canvas>
    <br />
    <fieldset>
      <legend>Image Data</legend>
      <textarea id="imageString"></textarea>

      <img id="imageOutput" src="" />
    </fieldset>
  </body>
</html>

我知道图像实际上并不是从&lt;input type='file' /&gt; 加载的,但我认为值得一试。在 Chrome 控制台中,我得到:

不允许加载本地资源

有什么方法可以让我将 iPad 中的图像放入画布元素中?

非常感谢任何帮助、提示或建议!谢谢!

【问题讨论】:

  • 使用 JavaScript,无论如何都无法访问本地文件系统。
  • 我害怕那个。关于离线时如何完成此任务的任何建议?
  • 我假设你不想使用&lt;input type='file' /&gt;?
  • 不,我愿意!我不知道有什么其他方法可以让 iPad 看照片

标签: javascript html


【解决方案1】:

我有一个functioning fiddle(基于this answer 的先前工作),它演示了如何使用文件输入上传图像,将其放置在画布中,然后读取 base64 数据 URL。

简而言之,您应该:

  1. 使用File API 读取图像(您可以在输入元素的onchange 侦听器中执行此操作):
var file = input.files[0];
var fr = new FileReader();
fr.onload = createImage;   // onload fires after reading is complete
fr.readAsDataURL(file);    // begin reading
  1. 在 FileReader 的 onload 回调(此处为 createImage)中,读取 FileReader 的 result(此处为 fr.result)。这是您的图片数据网址!

可选步骤(仅当您打算在画布上操作图像时才需要):

  1. 在 FileReader 的 onload 回调(此处为 createImage)中,创建一个新的 Image 对象并将其 src 设置为 FileReader 的 result
img = new Image();
img.onload = imageLoaded;
img.src = fr.result;
  1. 最后,在 Image 的 onload 回调中,将其绘制到画布上,然后将 canvas.toDataUrl 用于数据:
canvas.width = img.width;      // set canvas size big enough for the image
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0);         // draw the image

// do some manipulations...

canvas.toDataURL("image/png");  // get the data URL

【讨论】:

  • fr.readAsDataURL 会将result 设置为数据URL,因此无需通过new Image&lt;canvas&gt;,除非您打算在画布中编辑图像以获取不同的输出。
  • @PaulS。对,我想这有点过分了!我只做了canvas 的东西,因为它在 OP 的原始问题中——我会将无关的部分移到不同的部分,以防 OP 确实想要编辑图像。
  • 感谢您的好回答。我在 Safari 上尝试过,但它不起作用。你对此有什么建议吗? stackoverflow.com/questions/27860782/…
  • @AMG 如果您使用的是 readAsDataURL,则不需要对图像进行 onload 回调。因为它立即加载。事实上,我在 Firefox 中发现,如果我有回调它实际上不起作用。
  • 我收到了这条消息:Refused to load the image 'data:image/jpeg;base64,/9j/4AAQSkZ...2Sv/Z' because it violates the following Content Security Policy directive: "default-src 'self' 'unsafe-inline'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
【解决方案2】:

输入文件,上传文件后用javascript减小文件大小,再次传递输入文件值。

const input = document.getElementById("img-input");
input.onchange = function (ev) {
  const file    = ev.target.files[0]; // get the file
  const blobURL = URL.createObjectURL(file);
  const img     = new Image();
  img.src       = blobURL;

  img.onerror = function () {
    URL.revokeObjectURL(this.src);
    // Handle the failure properly
    console.log("Cannot load image");
  };

  img.onload = function () {
    URL.revokeObjectURL(this.src);
    const mime_type = "image/jpeg";
    const quality = qualityRate(file.size);
    const canvas  = document.createElement("canvas");
    canvas.width  = img.width;
    canvas.height = img.height;
    const ctx     = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);

    document.getElementById("root").append(canvas);
    //let data = canvas.toDataURL(mime_type,quality);
    //downloadURI(data, 'stage.jpg');

    canvas.toBlob(blob => {
        let localfile = new File([blob], 'a.jpg',{type:"image/jpeg", lastModified:new Date().getTime()}, 'utf-8');
        let container = new DataTransfer();
        container.items.add(localfile);
        document.querySelector('#img-input').files = container.files;
    },mime_type,quality);
  };
};

function qualityRate(fileSize){
    let QUALITY = 0.5;
    
    if(1000000 > fileSize){
        QUALITY = 0.5;
    }
    else if(3000000 > fileSize){
        QUALITY = 0.7;
    }
    else if(5000000 > fileSize){
        QUALITY = 0.5;
    }
    else if(10000000 > fileSize){
        QUALITY = 0.9;
    }
    else{
        QUALITY = 0.1;
    }
    console.log(QUALITY);
    return QUALITY;
}

function downloadURI(uri, name) {
    var link = document.createElement('a');
    link.download = name;
    link.href = uri;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    delete link;
}
<form action="test.php" method="post" enctype="multipart/form-data">
    <input id="img-input" type="file" name="fileTest" accept="image/*" />
    <input type="submit" name="submit" value="aa">
</form>
<div id="root" style=" display: none; "></div>

【讨论】:

    猜你喜欢
    • 2016-08-19
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2011-03-17
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    相关资源
    最近更新 更多