如何在将图像从网页的 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。
如果图片是从您的网页拖拽过来的:
- 侦听
dragover
、drop
和可选的 dragenter
事件。
- 在处理所有 3 个事件时,告诉浏览器您正在使用
event.preventDefault
和可选的 event.stopPropagation
. 处理事件
- 在
drop
处理程序中,获取已删除图像的 event.dataTransfer.getData('text/plain') which fetches the
.src`。
- 使用
.src
和 drawImage
到 canvas 创建一个新的 Image()
对象。
如果图像是从您的本地驱动器拖动的:
1 & 2. 监听和处理与网页代码中相同的事件。
获取用户放置在event.dataTransfer.files
.
中的本地图像文件
创建一个FileReader
并读取每个图像文件。 FileReader.readAsDataURL
方法将 return 图像 URL,您可以将其用作图像对象的 .src
。
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>
这是后续问题
我根本不知道如何访问我放到 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。
如果图片是从您的网页拖拽过来的:
- 侦听
dragover
、drop
和可选的dragenter
事件。 - 在处理所有 3 个事件时,告诉浏览器您正在使用
event.preventDefault
和可选的event.stopPropagation
. 处理事件
- 在
drop
处理程序中,获取已删除图像的event.dataTransfer.getData('text/plain') which fetches the
.src`。 - 使用
.src
和drawImage
到 canvas 创建一个新的Image()
对象。
如果图像是从您的本地驱动器拖动的:
1 & 2. 监听和处理与网页代码中相同的事件。
获取用户放置在
event.dataTransfer.files
. 中的本地图像文件
创建一个
FileReader
并读取每个图像文件。FileReader.readAsDataURL
方法将 return 图像 URL,您可以将其用作图像对象的.src
。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>