前端开发系列029-基础篇之Canvas绘图(压缩)
写这篇文章的原因是因为今天早上的时候,突然遇到个需求需要等比例调整照片的大小(主要是想把图片等比例的缩小),我在Mac上通过图片处理软件捣鼓的时候发现比较麻烦,就随手百度了一个在线修改图片尺寸的网站,叫做[改图宝](http://www.gaitubao.com/)。这个网站提供给图片加logo、修改图片尺寸以及印章制作等诸多功能,界面简洁使用方便解决了我的问题,值得推荐。
然而,等到中午的时候,我发现还有一张图片需要处理,恰好电脑连不上网络,我就考虑能不能通过代码自己来实现,因为图片的选择 - 压缩 - 上传
在实际开发中也是对应的场景,因此本文将介绍如何利用Canvas画布来对图片进行压缩的技术,包括实现思路和具体的代码。
![](http://img.wendingding.vip/blog/canvas_38.png)
[ 1 ] 获取源图像数据
在页面中我们使用input标签(file类型)
来让用户选择对应的文件上传。为了等比例的对图片进行压缩,需要获取源图片的宽度和高度等数据参数,这里使用了FileReader构造函数(类)。
具体实现的时候,先调用new FileReader()
创建一个FileReader的实例对象,然后为input标签
注册change事件监听。当用户选择好文件后,需要先检查是否是图片(通过MIMEType类型判断),再通过FileReader实例来调用readAsDataURL(file)
方法来读取图片文件的数据信息,以获取源图片文件的宽度和高度信息。
[ 2 ] 计算宽高压缩比数据
因为示例代码中演示的等比例的进行缩放(压缩),因此需要通过得到目标图片的宽度和高度尺寸数据。
这里列出计算部分的核心代码
var targetWidth,targetHeight;
var imgWidth = img.width, imgHeight = img.height;
var maxWidth = 150, maxHeight = 150;
// 如果图片尺寸超过限制,那么需要重新计算宽高
if (imgWidth > maxWidth || imgHeight > maxHeight) {
if (imgWidth / imgHeight >= 1) {
// 如果更宽,那么就按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (imgHeight / imgWidth));
} else {
// 如果更高,那么就按照高度限定尺寸
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (imgWidth / imgHeight));
}
}
[ 3 ] 绘制目标图片
当目标图片(压缩后)的宽高都计算完成后,可以通过Canvas上下文的drawImage
方法来完成图片的绘制,该方法的具体使用可以参考[ javaScript系列 [14]-Canvas绘图(图像)](http://wendingding.com/2019/02/05/javaScript系列 [14]-Canvas绘图(图像)这篇文章。
drawImage
方法的第一个参数为需要绘制的图片数据,该图片数据即为用户通过input标签选择的文件内容。当然,在具体实现的时候还需要读取文件的内容,监听加载完毕之后再设置Image数据源。
reader.onload = function(event) {
/e.target.result是图片的base64地址信息
img.src = event.target.result;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="file" id="file">
<div id="info" style="font-size: 13px"></div>
<canvas id="canvas" height="200" width="200"></canvas>
<script>
//[1] 获取页面中的文件选择标签
var oInput = document.querySelector('#file');
//[2] 创建FileReader对象用于读取文件信息
var reader = new FileReader();
var file = null; //文件对象
//[3] 给文件选择标签添加事件监听
oInput.addEventListener('change', function (event) {
//001 获取用户选择的文件
file = event.target.files[0];
//002 获取文件的MIMEType类型
var fileType = file.type;
//003 检查用户选择的文件是否是图片
if (fileType.indexOf("image") == 0) {
//004 如果发现文件是图片则读取图片为DataURL
reader.readAsDataURL(file);
}
});
//[4] 创建Image图像实例
var img = new Image();
var targetWidth,targetHeight;
//[5] 监听FileReader对象是否处理完毕,设置图像实例的数据源
reader.onload = function(event) {
//说明:e.target.result是图片的base64地址信息
img.src = event.target.result;
}
//[6] 监听Image实例加载,压缩图片并生成预览图像
img.onload = function () {
setFileInfo();
//[7]在页面中创建canvas画布对图片进行缩放(压缩)后绘制
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
}
function setFileInfo() {
// 获取文件的名称
var fileName = file.name;
// 获取文件的大小
var fileSize = (file.size / 1024 / 1024).toFixed(3) + "M";
// 图片压缩比计算
var imgWidth = img.width, imgHeight = img.height;
var maxWidth = 150, maxHeight = 150;
// 如果图片尺寸超过限制,那么需要重新计算宽高
if (imgWidth > maxWidth || imgHeight > maxHeight) {
if (imgWidth / imgHeight >= 1) {
// 如果更宽,那么就按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (imgHeight / imgWidth));
} else {
// 如果更高,那么就按照高度限定尺寸
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (imgWidth / imgHeight));
}
//在页面中显示图片信息
var html = "<div>1.已选择图片" + fileName + ",大小为" + fileSize + "。</div>\n" +
"<div>2.图片原尺寸是:" + imgWidth + " x " + imgHeight + "</div>\n" +
"<div>3.图片压缩尺寸:" + maxWidth + " x " + maxHeight + "</div>\n" +
"<div>4.图片已压缩为:" + targetWidth + " x " + targetHeight +"</div>\n";
var oDiv = document.getElementById("info");
oDiv.innerHTML = html;
}
};
</script>
</body>
</html>
![](http://img.wendingding.vip/blog/canvas_37.gif)