查看: 257|回复: 1

HTML5 Canvas图片旋转与下载功能JavaScript实现详解

[复制链接]
发表于 5 天前 | 显示全部楼层 |阅读模式
在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()触发浏览器下载。

四、完整代码示例(基于原文逻辑整理)
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Canvas图片旋转与下载</title>
  8. <style>
  9. .download {
  10.     width: 100px;
  11.     height: 40px;
  12.     background-color: #fff;
  13.     color: #276787;
  14.     border: 1px solid #276787;
  15.     display: flex;
  16.     align-items: center;
  17.     justify-content: center;
  18.     border-radius: 20px;
  19.     cursor: pointer;
  20. }
  21. .download:hover {
  22.     background-color: #276787;
  23.     color: #fff;
  24.     border-color: transparent;
  25. }
  26. .download:active {
  27.     opacity: 0.4;
  28. }
  29. </style>
  30. </head>
  31. <body>
  32. <canvas id="canvas"></canvas>
  33. <div class="download">下载</div>
  34. <script>
  35. // 图片加载与旋转
  36. const canvas = document.getElementById('canvas');
  37. const ctx = canvas.getContext('2d');
  38. const originImage = new Image();
  39. originImage.crossOrigin = 'anonymous';
  40. originImage.src = 'https://example.com/sample.jpg'; // 替换为实际图片URL
  41. originImage.onload = function() {
  42.     const ow = originImage.width;
  43.     const oh = originImage.height;
  44.    
  45.     // 180度旋转实现
  46.     canvas.width = ow;
  47.     canvas.height = oh;
  48.     ctx.rotate(Math.PI);
  49.     ctx.drawImage(originImage, -ow, -oh);
  50.     ctx.setTransform(1, 0, 0, 1, 0, 0);
  51.    
  52.     // 90度旋转(注释为例,可开启使用)
  53.     // canvas.width = oh;
  54.     // canvas.height = ow;
  55.     // ctx.rotate(-Math.PI / 2);
  56.     // ctx.drawImage(originImage, -ow, 0);
  57.     // ctx.rotate(Math.PI / 2);
  58.     // ctx.setTransform(1, 0, 0, 1, 0, 0);
  59. };
  60. // Base64转Blob工具函数
  61. function base64ToBlob(base64) {
  62.     const arr = base64.split(',');
  63.     const mime = arr[0].match(/:(.*?);/)[1];
  64.     const bstr = atob(arr[1]);
  65.     let n = bstr.length;
  66.     const u8arr = new Uint8Array(n);
  67.     while (n--) {
  68.         u8arr[n] = bstr.charCodeAt(n);
  69.     }
  70.     return new Blob([u8arr], {type: mime});
  71. }
  72. // 下载按钮事件
  73. document.querySelector('.download').addEventListener('click', function() {
  74.     const base64 = canvas.toDataURL('image/jpeg', 0.5);
  75.     const blob = base64ToBlob(base64);
  76.     const url = URL.createObjectURL(blob);
  77.     const a = document.createElement('a');
  78.     a.href = url;
  79.     a.download = '旋转后的图片.jpg';
  80.     a.click();
  81.     URL.revokeObjectURL(url); // 释放内存
  82. });
  83. </script>
  84. </body>
  85. </html>
复制代码

五、总结
本实现通过Canvas的rotate与drawImage组合完成图片旋转,利用toDataURL结合Blob对象实现下载。开发者可灵活调整旋转角度、输出格式与质量,注意跨域图片需服务器支持CORS。此方案适合在纯前端环境下完成简单图像编辑与导出。
回复

使用道具 举报

发表于 5 天前 | 显示全部楼层

Re: HTML5 Canvas图片旋转与下载功能JavaScript实现详解

非常感谢楼主的详细分享,代码结构清晰,注释也很完整,对刚接触Canvas的开发者来说是非常实用的教程。 我注意到在 `base64ToBlob` 函数中有一个小笔误:`u8arr = bstr.charCodeAt(n);` 这行会不断覆盖变量而非填充数组,应该是 `u8arr = bstr.charCodeAt(n);`。另外,处理跨域图片时,如果图片服务器不支持 `crossOrigin`,可能会报错,建议加一个错误回调(`onerror`)做友好提示。 CSS按钮的交互细节(悬停反色、按下透明度)也做得很用心,这种小细节能提升用户体验。90度旋转的原理说明也很到位,方便读者灵活调整角度。整体内容实用且完整,收藏了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-14 05:30 , Processed in 0.025748 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部