Canvas生成缩略图
source link: https://www.clzczh.top/2022/06/18/Canvas%E7%94%9F%E6%88%90%E7%BC%A9%E7%95%A5%E5%9B%BE/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Canvas生成缩略图
个人博客的图片太大了,想换成缩略图,正好学了点Canvas,发现用Canvas画出来的图片就有点缩略图的感觉,于是就开始搞起来了
利用canvas实现绘制图片
先通过canvas.getContext('2d')
获取2D绘图上下文,然后调用绘图上下文的drawImage
方法,实现图片的绘制。详情可查看之前写的Canvas的文章。
<canvas id="mycanvas" width="640" height="360"></canvas>
const mycanvas = document.getElementById('mycanvas')
const context = mycanvas.getContext("2d");
// 获取图像
const img = new Image();
img.src = "./big.png";
// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
context.drawImage(img, 0, 0, 640, 360);
}
上面我们就已经绘制图片了,但是下载图片比较麻烦,得通过右键浏览器自带的另存方法。
所以我们可以通过Canvas的toDataURL
方法,将绘制的图片转成base64
编码,然后通过a链接
方式下载。具体的下载方法的实现同样可以查看以前写的文章。(偷懒,不想贴地址,手动狗头)
const mycanvas = document.getElementById('mycanvas')
const context = mycanvas.getContext("2d");
// 获取图像
const img = new Image();
img.src = "./big.png";
// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
context.drawImage(img, 0, 0, 640, 360);
const a = document.createElement('a')
a.href = mycanvas.toDataURL()
// 获取源图片的名字
a.download = img.src.split('/')[img.src.split('/').length - 1]
a.click()
}
刷新页面,我们就能发现自动下载了。接下来,我们就来看看,是不是我们想要的效果。
去掉html结构中的canvas
实际上,我们可以自己生成Canvas,然后设置宽高,这样就不需要上DOM树,也能实现下载图片。
const w = 640
const h = 360
const mycanvas = document.createElement('canvas')
mycanvas.width = w
mycanvas.height = h
const context = mycanvas.getContext("2d");
// 获取图像
const img = new Image();
img.src = "./big.png";
// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
context.drawImage(img, 0, 0, w, h);
const a = document.createElement('a')
a.href = mycanvas.toDataURL()
// 获取源图片的名字
a.download = img.src.split('/')[img.src.split('/').length - 1]
a.click()
}
使用input:file
实现生成多张缩略图
因为安全的关系,网页中的js访问文件夹下的图片会有很多限制。所以选了一个比较简单地方法,利用input:file
来实现。通过input:file
的files
属性可以访问选择的文件列表。
下面为了方便,使用了form
元素,通过 document.form[0]
方式访问form
元素,通过form.elements[0]
访问input
元素。
<form action="#">
<input type="file" multiple>
</form>
<button onclick="generatePreview()">生成缩略图</button>
const w = 640
const h = 360
function generatePreview() {
const files = document.forms[0].elements[0].files
console.log(files)
}
这样子就能够获取选中的文件信息了,但是实际上我们只需要文件数量信息和文件名信息即可。
遍历图片列表,下载图片。(图片的src
属性需要改成对应文件名,生成的图片也需要更改名字。)
a.download = fileName.replace(/(\w+)/, '$1_preview')
这里我使用的是正则表达式+replace
方法去修改名字(简单版本,勿喷)
\w
:匹配一个单字字符(字母、数字或者下划线)。等价于[A-Za-z0-9_]
+
:匹配前面一个表达式 1 次或者多次$1
:捕获匹配项,前面的正则表达式中,使用括号包住了\w+
,所以$1
实际上就是这部分
完整代码:(html
文件要放到图片文件夹下才有效)
<body>
<form action="#">
<input type="file" multiple>
</form>
<button onclick="generatePreview()">生成缩略图</button>
<script>
const w = 640
const h = 360
function generatePreview() {
const files = document.forms[0].elements[0].files
for (const file of files) {
const fileName = file.name
console.log(file)
const mycanvas = document.createElement('canvas')
mycanvas.width = w
mycanvas.height = h
const context = mycanvas.getContext("2d");
// 获取图像
const img = new Image();
img.src = `./${fileName}`;
// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
context.drawImage(img, 0, 0, w, h);
const a = document.createElement('a')
a.href = mycanvas.toDataURL()
// 获取源图片的名字
a.download = fileName.replace(/(\w+)/, '$1_preview')
a.click()
}
}
}
</script>
</body>
另外,直接本地打开,执行会报错,因为没有服务器环境,本地的html网页,本地的图片
本地的位置是没有域名的,所以会认为是跨域,会报错,可以使用VSCode
的Live Server
插件,然后右键,点击Open with Live Server
就能够以服务器环境打开。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK