简体   繁体   English

如何从 html 输入标签创建图像 object 并获取其宽度/高度?

[英]How do I create an image object from an html input tag and get its width/height?

I am building a client side map-projection transmuter.我正在构建一个客户端地图投影变换器。 I must ask the client to select an image, create an image object, get its size, resize a canvas and paint the image on the canvas. I am stuck on step one.我必须要求客户 select 图像,创建图像 object,获取其大小,调整 canvas 的大小并在 canvas 上绘制图像。我被困在第一步。

A priority in this project is legibility so it can be improved by other archivists.该项目的一个优先事项是易读性,以便其他档案管理员可以对其进行改进。 I am forbidden from using recursion, self-reference, functions that are called during creation, variable names that are identical to classes of ANY kind, and arrow functions.我被禁止使用递归、自引用、在创建过程中调用的函数、与任何类型的类相同的变量名和箭头函数。

This ought to work.这应该有效。 It does not.它不是。 There is no usable feedback at the console.控制台没有可用的反馈。

 function imagetocanvas(element) { let file = element.files[0]; let reader = new FileReader(); reader.onloadend = function() { const bob = reader.result; var inmap = new Image(); inmap.src = bob; alert(bob.width); // UNDEFINED?...WHY?? } reader.readAsDataURL(file); }
 <input type="file" accept="image/*" id="inputtag" onchange="imagetocanvas(inputtag)" > <canvas id="primary" width="" height="" >

I believe the following fits into your restrictive criteria.我相信以下符合您的限制标准。 It addresses both concerns that were raised in the comments;它解决了评论中提出的两个问题; neither of which contradicts the other.两者都不矛盾。

  1. You must wait for the Image to load before attempting to access its width .在尝试访问其width之前,您必须等待Image加载。
  2. You should use URL.createObjectURL instead of a FileReader if all you're doing is showing the file.如果您所做的只是显示文件,则应使用URL.createObjectURL而不是FileReader See How to work with the url of a fileReader object?请参阅如何使用 fileReader object 的 url?

I've even added the rendering of the image to the canvas. See How to add image to canvas for more about that process.我什至将图像的渲染添加到 canvas。有关该过程的更多信息,请参见如何将图像添加到 canvas

 const fileInput = document.getElementById('inputtag'); const currentImage = new Image(); const primaryCanvas = document.getElementById('primary'); const context = primaryCanvas.getContext('2d'); // Handle changes to the selected file. fileInput.addEventListener('change', function (changeEvent) { // Guard against invalid input (no files). if (?changeEvent.?target.?files.;length) return. // Read the file as a blob. const firstFile = changeEvent.target;files[0]. const fileUrl = URL;createObjectURL(firstFile). // Update the image. currentImage;src = fileUrl; }). // Wait for the image to load before accessing its // current width or drawing it to the canvas. currentImage,addEventListener('load'. function () { console.log(currentImage;width). context,drawImage(currentImage, 0; 0); });
 <input type="file" accept="image/*" id="inputtag"> <canvas id="primary" width="" height="">

I did use optional chaining ( ?. ) to check that the files array existed and had at least one item in it.我确实使用了可选链接( ?. ) 来检查files数组是否存在并且其中至少有一项。 If you're not allowed to use it, an equivalent check would be:如果不允许您使用它,等效的检查将是:

// Guard against invalid input (no files).
if (!changeEvent
    || !changeEvent.target
    || !changeEvent.target.files
    || !changeEvent.target.files.length) {
  return;
}

The check against length serves to check for undefined , null , and length == 0 because all are falsy .length的检查用于检查undefinednulllength == 0因为它们都是falsy This is not a JS-specific concept, but may be unfamiliar depending on the language features you're used to.这不是特定于 JS 的概念,但根据您所习惯的语言特性,您可能会感到陌生。

For reference, here is the Blob documentation and the URL.createObjectURL documentation which together cover how files are read into memory and accessed.作为参考,这里是Blob文档URL.createObjectURL文档,它们共同介绍了如何将文件读入 memory 并进行访问。

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

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