HTML5 Canvas 是一个非常酷的功能。它看似只是一个在浏览器内用低级 API 绘画的机会,但实际上你可以用它来大量转换和修改文档中的图像和视频内容。今天,让我们快速了解一下如何使用 Canvas 和 FileReader API 从拖放到浏览器文档中的图像创建缩略图。
最终代码在 GitHub 上,你可以在 这里查看在线演示。YouTube 上也有一段屏幕录制。
步骤 1:将文件导入浏览器
在浏览器中调整图像大小的第一步是获取它们。为此,我们可以在页面中添加一个元素,并为其分配拖放事件处理程序
s.addEventListener( 'dragover', function ( evt ) {
evt.preventDefault();
}, false );
s.addEventListener( 'drop', getfiles, false );
请注意,我们只在将东西拖放到元素上时才阻止默认行为。这是为了防止浏览器在将图像拖入时只显示它们。
然后 getfiles()
函数完成繁重的工作,读取所有文件并将其发送到执行调整大小和图像生成的函数。
function getfiles( ev ) {
var files = ev.dataTransfer.files;
if ( files.length > 0 ) {
var i = files.length;
while ( i-- ) {
var file = files[ i ];
if ( file.type.indexOf( 'image' ) === -1 ) { continue; }
var reader = new FileReader();
reader.readAsDataURL( file );
reader.onload = function ( ev ) {
var img = new Image();
img.src = ev.target.result;
img.onload = function() {
imagetocanvas( this, thumbwidth, thumbheight, crop, background );
};
};
}
}
ev.preventDefault();
};
drop
事件提供了一个名为 dataTransfer
的属性,其中包含所有已拖放文件的列表。我们确保至少有一个文件被拖放,然后遍历它们。
如果文件类型不是图像(或者换句话说,文件的 type 属性不包含字符串“image”),我们不会对该文件进行任何操作,并继续循环。
如果文件是图像,我们实例化一个新的 FileReader
并告诉它将文件读取为数据 URL。当读取器成功加载文件时,它会触发其 onload
处理程序。
在这个处理程序中,我们创建一个新的图像,并将它的 src
属性设置为文件传输的 result
。然后,我们将此图像发送到 imagetocanvas()
函数,并附带要调整大小的参数(在演示中,这些参数来自表单)。
function imagetocanvas( img, thumbwidth, thumbheight, crop, background ) {
c.width = thumbwidth;
c.height = thumbheight;
var dimensions = resize( img.width, img.height, thumbwidth, thumbheight );
if ( crop ) {
c.width = dimensions.w;
c.height = dimensions.h;
dimensions.x = 0;
dimensions.y = 0;
}
if ( background !== 'transparent' ) {
cx.fillStyle = background;
cx.fillRect ( 0, 0, thumbwidth, thumbheight );
}
cx.drawImage(
img, dimensions.x, dimensions.y, dimensions.w, dimensions.h
);
addtothumbslist( jpeg, quality );
};
此函数获取所需的缩略图大小,并将画布调整为这些尺寸。这样做的好处是会清空画布,这样就不会将任何旧的图像数据添加到我们的缩略图中。然后,我们使用 resize()
函数将图像调整为适合缩略图。你可以在源代码中自己查看此函数的作用,它只是意味着图像会调整为适合。该函数返回一个对象,其中包含新图像的宽度和高度,以及它应该放置在画布上的 x 和 y 位置。
如果我们不想要全尺寸缩略图,而是要裁剪它,则相应调整画布大小,并将 x 和 y 重置为 0。
如果用户请求背景,我们用颜色填充画布。之后,我们将图像放置在画布上,使用 x 和 y 坐标以及新的宽度和高度。
这负责在画布上创建新的缩略图,但我们还没有将其作为文档中的图像获取。为此,我们调用 addtothumbslist()
。
function addtothumbslist( jpeg, quality ) {
var thumb = new Image(),
url = jpeg ? c.toDataURL( 'image/jpeg' , quality ) : c.toDataURL();
thumb.src = url;
thumb.title = Math.round( url.length / 1000 * 100 ) / 100 + ' KB';
o.appendChild( thumb );
};
这个函数创建一个新的图像,并检查用户是否想要创建 JPG 或 PNG 图像。PNG 图像往往具有更好的质量,但文件大小也更大。如果请求了 JPG,我们调用画布的 toDataURL()
方法,并使用两个参数:请求的 JPEG MIME 类型和图像质量(介于 0 到 1 之间,1 为最佳质量)。如果需要 PNG,我们只需调用 toDataURL()
即可,无需任何参数,因为这是默认设置。
我们将图像的 src
设置为生成的 url 字符串,并添加一个标题,显示图像的大小(以 KB 为单位,四舍五入到两位小数)。接下来要做的就是将缩略图添加到页面上的输出元素中。
就是这样,你就可以将图像拖放到浏览器中以生成缩略图了。目前,我们只能一次保存一个缩略图(或者如果你有一些下载插件,则可以一次保存多个)。如果将 Zip.js 添加到混合中以将其作为 zip 提供,那会很有趣。我敢你试试!:)
更多阅读
- 拖放 在 MDN 上
- FileReader 在 MDN 上
- Canvas 在 MDN 上
关于 Chris Heilmann
HTML5 和开放网络的福音传道者。让我们修复它!
6 条评论