在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[0].match(/:(.*?);/)[1];
- const bstr = atob(arr[1]);
- let n = bstr.length;
- const u8arr = new Uint8Array(n);
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new Blob([u8arr], {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。此方案适合在纯前端环境下完成简单图像编辑与导出。 |