HTML5 Canvas图片旋转与下载功能JavaScript实现详解
在Web前端开发中,利用HTML5 Canvas对图片进行旋转并实现下载是一个常见需求。本文围绕一段完整的脚本代码,解析如何通过Canvas API实现图片的180度旋转,以及基于Blob的下载功能,并附带90度旋转的实现原理,方便读者按需扩展。一、HTML结构概述
页面包含一个<canvas>元素(id为canvas)用于图像绘制,以及一个类名为download的按钮,点击触发下载。Canvas后备文本提示浏览器兼容性。
二、CSS样式要点
按钮通过.flex居中,设置宽度100px、高度40px、白色背景、#276787边框和文字颜色,圆角20px。鼠标悬停时背景与文字颜色互换,按下时透明度变为0.4,提供清晰的交互反馈。
三、JavaScript核心实现
1. 图像加载与Canvas初始化
创建一个Image对象加载外部图片,设置crossOrigin为anonymous以处理跨域。图片加载完成后,获取原始宽高ow、oh,并设置canvas宽高。
2. 旋转实现(180度)
将画布宽高设为ow和oh,使用ctx.rotate(Math.PI)顺时针旋转180度,然后绘制图片时偏移(-ow, -oh)至正确位置。最终通过ctx.setTransform(1,0,0,1,0,0)恢复坐标系。
(注:90度旋转原理类似,只需将canvas宽高互换,旋转角度改为-90度,绘绘制偏移(-ow,0),开发者可根据需求在代码中开启注释部分。)
3. 生成Base64与转换为Blob
使用canvas.toDataURL('image/jpeg',0.5)生成JPEG格式的低质量Base64字符串。工具函数base64ToBlob负责解析Base64:提取MIME类型,用atob解码为二进制字符串,再转为Uint8Array,最后构造Blob对象。
4. 下载触发
动态创建<a>元素,通过URL.createObjectURL(blob)生成Object URL,赋值给href,并指定download属性为“旋转后的图片.jpg”。最后调用click()触发浏览器下载。
四、完整代码示例(基于原文逻辑整理)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas图片旋转与下载</title>
<style>
.download {
width: 100px;
height: 40px;
background-color: #fff;
color: #276787;
border: 1px solid #276787;
display: flex;
align-items: center;
justify-content: center;
border-radius: 20px;
cursor: pointer;
}
.download:hover {
background-color: #276787;
color: #fff;
border-color: transparent;
}
.download:active {
opacity: 0.4;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div class="download">下载</div>
<script>
// 图片加载与旋转
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const originImage = new Image();
originImage.crossOrigin = 'anonymous';
originImage.src = 'https://example.com/sample.jpg'; // 替换为实际图片URL
originImage.onload = function() {
const ow = originImage.width;
const oh = originImage.height;
// 180度旋转实现
canvas.width = ow;
canvas.height = oh;
ctx.rotate(Math.PI);
ctx.drawImage(originImage, -ow, -oh);
ctx.setTransform(1, 0, 0, 1, 0, 0);
// 90度旋转(注释为例,可开启使用)
// canvas.width = oh;
// canvas.height = ow;
// ctx.rotate(-Math.PI / 2);
// ctx.drawImage(originImage, -ow, 0);
// ctx.rotate(Math.PI / 2);
// ctx.setTransform(1, 0, 0, 1, 0, 0);
};
// Base64转Blob工具函数
function base64ToBlob(base64) {
const arr = base64.split(',');
const mime = arr.match(/:(.*?);/);
const bstr = atob(arr);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr = bstr.charCodeAt(n);
}
return new Blob(, {type: mime});
}
// 下载按钮事件
document.querySelector('.download').addEventListener('click', function() {
const base64 = canvas.toDataURL('image/jpeg', 0.5);
const blob = base64ToBlob(base64);
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '旋转后的图片.jpg';
a.click();
URL.revokeObjectURL(url); // 释放内存
});
</script>
</body>
</html>
五、总结
本实现通过Canvas的rotate与drawImage组合完成图片旋转,利用toDataURL结合Blob对象实现下载。开发者可灵活调整旋转角度、输出格式与质量,注意跨域图片需服务器支持CORS。此方案适合在纯前端环境下完成简单图像编辑与导出。
Re: HTML5 Canvas图片旋转与下载功能JavaScript实现详解
非常感谢楼主的详细分享,代码结构清晰,注释也很完整,对刚接触Canvas的开发者来说是非常实用的教程。 我注意到在 `base64ToBlob` 函数中有一个小笔误:`u8arr = bstr.charCodeAt(n);` 这行会不断覆盖变量而非填充数组,应该是 `u8arr = bstr.charCodeAt(n);`。另外,处理跨域图片时,如果图片服务器不支持 `crossOrigin`,可能会报错,建议加一个错误回调(`onerror`)做友好提示。 CSS按钮的交互细节(悬停反色、按下透明度)也做得很用心,这种小细节能提升用户体验。90度旋转的原理说明也很到位,方便读者灵活调整角度。整体内容实用且完整,收藏了!Re: HTML5 Canvas图片旋转与下载功能JavaScript实现详解
很实用的教程!Canvas旋转图片再下载这个场景在实际项目中确实经常遇到。180度旋转通过`rotate(Math.PI)`配合偏移量来定位,逻辑很清晰。另外你提到的90度旋转把宽高互换的思路也让扩展变得很方便。 一个小建议:Base64转Blob那个函数里,`u8arr`赋值那里可能有个笔误,写成了数组赋值给变量然后转换下标,实际上应该把每个字符的编码循环赋值给Uint8Array的对应位置。另外实际使用中可以考虑加个图片加载中的状态提示,或者错误处理(比如图片跨域加载失败的情况),这样用户体验会更完整。 整体代码结构很规范,注释也到位,感谢分享!Re: HTML5 Canvas图片旋转与下载功能JavaScript实现详解
感谢楼主分享这么详细的教程,从HTML结构到JS实现都梳理得很清楚,特别是180度旋转的坐标系偏移逻辑讲得很直观。我在实际测试代码时发现一个小的细节:`base64ToBlob`函数里的while循环中,`u8arr = bstr.charCodeAt(n)`这一句应该是`u8arr = bstr.charCodeAt(n)`才对,否则数组不会被正确填充,生成的blob可能会损坏。另外,现在大部分浏览器支持`canvas.toBlob()`直接获取Blob,可以省去Base64转码步骤,代码会更简洁。总之这篇文对Canvas旋转下载的常见问题覆盖得很全,收藏了!
页:
[1]