将图像从网页的html部分放到画布上后如何访问图像数据?

时间:2016-01-15 17:45:51

标签: firefox canvas drag-and-drop

这是一个后续问题 How to drop texts and images on a canvas? (Firefox 41.0.1)

我根本无法找到如何访问我放到画布上的图像的图像数据。我试过像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属性。)

2 个答案:

答案 0 :(得分:3)

您的用户可能会执行这两个版本中的一个(或两个):

  • 将img元素从网页拖到画布上,或
  • 将图像文件从本地驱动器拖到画布上。

如果正在从您的网页拖动图片:

  1. 倾听dragoverdrop以及dragenterevent.preventDefault事件。
  2. 处理所有3个活动时,请告知浏览器您使用event.stopPropagationdrop选择处理活动。
  3. event.dataTransfer.getData('text/plain') which fetches the处理程序中,获取已删除图片的Image()。src`。
  4. 使用.srcdrawImage在画布上创建新的event.dataTransfer.files对象。
  5. 如果正在从本地驱动器中拖动图像:

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

    1. 获取用户放置的FileReader放置的本地图像文件。

    2. 创建FileReader.readAsDataURL并阅读每个图像文件。 .src方法将返回一个图片网址,您可以将其用作图片对象的drawImage

    3. <!doctype html> <html> <head> <style> body{ background-color: ivory; } #canvas{border:1px solid red; margin:0 auto; } </style> <script> 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(){}); </script> </head> <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 id='sunny' src='https://dl.dropboxusercontent.com/u/139992952/multple/sunny.png'> <img id='rainy' src='https://dl.dropboxusercontent.com/u/139992952/multple/rainy.png'> <img id='stars' src='https://dl.dropboxusercontent.com/u/139992952/multple/stars.png'> </body> </html> 每个新图片都显示在画布上。

    4. 这是允许两者的示例代码:

      {{1}}

答案 1 :(得分:1)

这是我用来玩图像的一组(精简版)工具

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);

使用imageTools后将数据放回图像

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

从drop事件中获取可能包含多个图像的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();
    }
}

请注意,这只是一个示例,不是跨浏览器解决方案。您必须实现各种drop Manager以覆盖所有浏览器。这适用于Chrome,因此覆盖了大多数用户。