如何在将图像从网页的 html 部分拖放到 canvas 后访问图像数据?

How to access the image data after dropping an image from the html-part of a webpage onto a canvas?

这是后续问题

我根本不知道如何访问我放到 canvas 上的图像的图像数据。我尝试了 data = event.dataTransfer.getData("image") 之类的方法,但都不起作用。

function addDragNDropToCanvas() {
    document.getElementById('canvas').addEventListener("dragover", function(event) { event.preventDefault();}, false);
    //handle the drop
    document.getElementById('canvas').addEventListener("drop", function(event) {
        event.preventDefault();
        console.log('something is dropped on the object with id: ' + event.target.id);
        // var directData=event.dataTransfer.getData("image");
        console.log(event);
        }, false);

 }

肯定有图像数据包含在掉落事件数据中?不是吗??? (图片没有自己的 id 属性。)

这是我用来处理图像的一组(简化的)工具

var imageTools = (function () {
    var tools = {
        canvas : function (width, height) {  // create a blank image (canvas)
            var c = document.createElement("canvas");
            c.width = width;
            c.height = height;
            return c;
        },
        createImage : function (width, height) {
            var image = this.canvas(width, height);
            image.ctx = image.getContext("2d");
            return image;
        },
        loadImage : function (url, callback) {
            var image = new Image();
            image.src = url;
            image.addEventListener('load', cb);
            image.addEventListener('error', cb);
            return image;
        },
        image2Canvas : function (img) {
            var image = this.canvas(img.width, img.height);
            image.ctx = image.getContext("2d");
            image.drawImage(ig, 0, 0);
            return image;
        },
        getImageData : function (image) {
            return (image.ctx || (this.image2Canvas(image).ctx)).getImageData(0, 0, image.width, image.height).data;
        },
    };
    return tools;
})();

解析后得到全局变量imageTools

要加载和获取图像数据,您必须等待图像加载回调。

var image;
var imageData;
function loaded(event){
    if(event.type === "load"){
        image = imageTools.image2Canvas(this);
        imageData = imageTools.getImageData(image);
        // image data is now in the typed array
        // imageData.data
        // with imageData.width and imageData.height holding the size
        // there are 4 bytes per pixel in the form RGBA
    }
}
imageTools.loadImage(imageURL,loaded);

使用图像工具后将数据放回图像

// image.ctx is non standard and is a result of the imageTools adding the 
// attribute ctx
image.ctx.putImageData(imageData,0,0);

从可能不止一张图片的拖放事件中获取URL

var fileList = []; // a list of dropped images
// function called when images dropped
var imagesDropped = function(){
    fileList.forEach(function(image){
        // image.name is the image URL
        // image.type is the mime type    
    });
    fileList = []; // clear the file list
}
var dropEvent = function (event) {
    var i,j, imagesFound;
    imagesFound = false;
    event.preventDefault();
    dt = event.dataTransfer;
    for (i = 0; i < dt.types.length; i++) {  // for each dropped item
        if (dt.types[i] === "Files") { // content from the file system
            for (var j = 0; j < dt.files.length; j++) {
                // check the mime type for the image prefix
                if (dt.files[j].type.indexOf("image/") > -1){
                    fileList.push({  // add to image list
                        name : dt.files[j].name,
                        type : dt.files[j].type,
                    });
                    imagesFound = true;  // flag images found
                }
            }
        }
    }
    if(imagesFound){ // if images dropped call the handling function
        imagesDropped();
    }
}

请注意,这只是一个示例,并非跨浏览器解决方案。您将不得不实施各种覆盖所有浏览器的放置管理器。这适用于 Chrome,因此涵盖了大多数用户。

您的用户可能会进行以下两种拖动中的一种(或两种):

  • 将 img 元素从您的网页拖到 canvas 或
  • 将图像文件从本地驱动器拖到 canvas。

如果图片是从您的网页拖拽过来的:

  1. 侦听 dragoverdrop 和可选的 dragenter 事件。
  2. 在处理所有 3 个事件时,告诉浏览器您正在使用 event.preventDefault 和可选的 event.stopPropagation.
  3. 处理事件
  4. drop 处理程序中,获取已删除图像的 event.dataTransfer.getData('text/plain') which fetches the.src`。
  5. 使用 .srcdrawImage 到 canvas 创建一个新的 Image() 对象。

如果图像是从您的本地驱动器拖动的:

1 & 2. 监听和处理与网页代码中相同的事件。

  1. 获取用户放置在event.dataTransfer.files.

  2. 中的本地图像文件
  3. 创建一个FileReader并读取每个图像文件。 FileReader.readAsDataURL 方法将 return 图像 URL,您可以将其用作图像对象的 .src

  4. drawImage每张新图片到canvas.

下面是允许两者的示例代码:

    window.onload=function(){

        // canvas related vars
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");

        // dropZone event handlers
        var dropZone=document.getElementById("canvas");
        dropZone.addEventListener("dragenter", handleDragEnter, false);
        dropZone.addEventListener("dragover", handleDragOver, false);
        dropZone.addEventListener("drop", handleDrop, false);
        //
        function handleDragEnter(e){e.stopPropagation(); e.preventDefault();}
        //
        function handleDragOver(e){e.stopPropagation(); e.preventDefault();}
        //
        function handleDrop(e){
            e.stopPropagation();
            e.preventDefault();
            //
            var url=e.dataTransfer.getData('text/plain');
            // for img elements, url is the img src so 
            // create an Image Object & draw to canvas
            if(url){
                var img=new Image();
                img.onload=function(){ctx.drawImage(this,0,0);}
                img.src=url;
            // for img file(s), read the file & draw to canvas
            }else{
                handleFiles(e.dataTransfer.files);
            }
        }
        // read & create an image from the image file
        function handleFiles(files) {
            for (var i=0;i<files.length;i++) {
              var file = files[i];
              var imageType = /image.*/;
              if (!file.type.match(imageType)){continue;}
              var img = document.createElement("img");
              img.classList.add("obj");
              img.file = file;
              var reader=new FileReader();
              reader.onload=(function(aImg){
                  return function(e) {
                      aImg.onload=function(){
                          ctx.drawImage(aImg,0,0);
                      }
                      // e.target.result is a dataURL for the image
                      aImg.src = e.target.result;
                  }; 
              })(img);
              reader.readAsDataURL(file);      
            } // end for
        } // end handleFiles

    }; // end $(function(){});
    body{ background-color: ivory; }
    #canvas{border:1px solid red; margin:0 auto; }
    <!doctype html>
    <html>
        <body>
            <h4>Drag an image from below onto the canvas, or<br>Drag an image file from your desktop onto the canvas.</h4>
            <canvas id="canvas" width=300 height=300></canvas>
            <br>
            <img width="50" src="https://cfl.dropboxstatic.com/static/images/index/rebrand/logos/glyphs/glyph_french_vanilla.svg">
        </body>
    </html>