网站首页 > 知识剖析 正文
整个过程用到了画布(canvas)来帮忙完成
过程: 选择图片文件 > 准备画布 > 按需压缩图片并绘制在画布上 > 生成Base64 > 完成.
先上效果图
详细过程如下:
准备一个简洁的HTML文件, 代码如下
用一个file dom来选择图片文件
Bash
<!DOCTYPE html>
<html lang="zh-CN">
<script type="text/javascript" src="../js/jquery.min.js"></script>
<body>
<input name="file" id="thumbnail" type="file" onchange="previewPic(this)"
accept="image/x-png, image/jpg, image/jpeg, image/gif" />
</body>
</html>
为了方便后面的代码操作, 引用了JQuery
然后准备2个容器, 一个放预览图; 另一个放Base64内容
Bash
<div>下面这个Div用来预览图片</div>
<div id="showpic" style="padding:7px;"></div>
<div>下面这个Div用来存放Base64内容</div>
<div id="picb64"></div>
接下来是灵魂:JS代码
function previewPic(tis) {
var fileObj = tis.files[0]; //获取图片文件对象
if (undefined == fileObj) { console.log("未选择待上传的文件"); return; }
var picid = "imgComp";
$("<img>", {
id: picid,
}).appendTo($("#showpic")); //先生成IMG的DOM,以防顺序乱掉
genCompPic(picid, fileObj);
}
function genCompPic(picid, fileObj) {
var ready = new FileReader();
/*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
ready.readAsDataURL(fileObj);
ready.onload = function () {
canvasDataURL(this.result, { width: 200 }, function (base64Codes) {
$("#"+ picid).attr("src", base64Codes); //在IMG DOM中显示图片预览
$("#picb64").html(base64Codes); //得到Base64结果,填充到Div中显示
})
}
}
//利用canvas生成压缩后的图片
function canvasDataURL(path, obj, callback) {
var img = new Image();
img.src = path;
img.onload = function () {
var w = obj.width;
var h = obj.width / (this.width/ this.height); //按比例压缩,计算出等比例高
var canvas = document.createElement('canvas'); //生成canvas
var ctx = canvas.getContext('2d');
// 创建属性节点
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw); //设置图片宽
canvas.setAttributeNode(anh); //设置图片高
ctx.drawImage(this, 0, 0, w, h); //绘制图片
var quality = 1; // 图片质量为0.1~1, quality值越小,所绘制出的图像越模糊
var base64 = canvas.toDataURL('image/jpeg', quality); //利用canvas生成Base64
callback(base64); // 回调函数返回base64的值
}
}
虽然有点长, 不过关键位置都写上注释了, 大家可以参考使用
如果不想压缩图片, 在canvasDataURL方法里可以把设置宽和高的代码换成原图参数即可
完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<script type="text/javascript" src="../js/jquery.min.js"></script>
<style>
#picb64{width: 95%;height: 300px;overflow-wrap: break-word;overflow: auto;margin: auto;background-color: #676767;border-radius: 10px;}
</style>
<body>
<input name="file" id="thumbnail" type="file" onchange="previewPic(this)"
accept="image/x-png, image/jpg, image/jpeg, image/gif" />
<div>下面这个Div用来预览图片</div>
<div id="showpic" style="padding:7px;"></div>
<div>下面这个Div用来存放Base64内容</div>
<div id="picb64"></div>
<script>
function previewPic(tis) {
var fileObj = tis.files[0]; //获取图片文件对象
if (undefined == fileObj) { console.log("未选择待上传的文件"); return; }
var picid = "imgComp";
$("<img>", {
id: picid,
}).appendTo($("#showpic")); //先生成IMG的DOM,以防顺序乱掉
genCompPic(picid, fileObj);
}
function genCompPic(picid, fileObj) {
var ready = new FileReader();
/*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
ready.readAsDataURL(fileObj);
ready.onload = function () {
canvasDataURL(this.result, { width: 200 }, function (base64Codes) {
$("#"+ picid).attr("src", base64Codes); //在IMG DOM中显示图片预览
$("#picb64").html(base64Codes); //得到Base64结果,填充到Div中显示
})
}
}
//利用canvas生成压缩后的图片
function canvasDataURL(path, obj, callback) {
var img = new Image();
img.src = path;
img.onload = function () {
var w = obj.width;
var h = obj.width / (this.width/ this.height); //按比例压缩,计算出等比例高
var canvas = document.createElement('canvas'); //生成canvas
var ctx = canvas.getContext('2d');
// 创建属性节点
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw); //设置图片宽
canvas.setAttributeNode(anh); //设置图片高
ctx.drawImage(this, 0, 0, w, h); //绘制图片
var quality = 0.8; // 图片质量为0.1~1, quality值越小,所绘制出的图像越模糊
var base64 = canvas.toDataURL('image/jpeg', quality); //利用canvas生成Base64
callback(base64); // 回调函数返回base64的值
}
}
</script>
</body>
</html>
扩展应用: 可以利用压缩后再上传来节省带宽
本期分享就酱紫, 下期再见[看]
复杂的问题简单化
每次只关注一个知识点
对技术有兴趣的小伙伴可以关注我, 以后会经常分享各种奇奇怪怪又实用的技术知识
猜你喜欢
- 2024-12-03 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
- 2024-12-03 HTML5 的一些小的整理吧
- 2024-12-03 前端架构101:MVC的不足与Flux的崛起
- 2024-12-03 一篇文章搞定form表单中上传图片控件使用技巧
- 2024-12-03 Python在selenium里面注入JavaScript程序的方法
- 2024-12-03 写给前端工程师的Flutter详细教程
- 2024-12-03 vue - Vue中的ajax
- 2024-12-03 开源适用于JavaScript的Excel解析器和生成器
- 2024-12-03 jQuery EasyUI使用教程:数据网格中的列运算
- 2024-12-03 详解React Flux架构工作方式
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)