Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >前端图片压缩及上传

前端图片压缩及上传

作者头像
OECOM
发布于 2020-07-02 03:46:07
发布于 2020-07-02 03:46:07
3K00
代码可运行
举报
文章被收录于专栏:OECOMOECOM
运行总次数:0
代码可运行

图片的上传一般情况下不需要上传大体积的图片,因为如果是用户头像或者是一些要求清晰度不是太高的场景上传大体积图片会很消耗资源,一个是上传耗时比较长,同时也增加了存储的开销,当展示的时候也会消耗下载的带宽,影响加载效率。要求用户上传的图片之前压缩图片很影响用户体验,所以就增加了在前端进行图片压缩的需求。

压缩方案

前端图片压缩的主要思路就是将图片绘制到canvas中,然后通过canvas的toDataURL方法来控制图片的质量,对图片进行压缩,另一方面是对图片进行宽高等比缩小来达到图片压缩的效果,下面来看一下代码示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 resizeMe(img,type, max_width, max_height) {
        var canvas = document.createElement('canvas');
        var width = img.width;
        var height = img.height;
        max_width = !isNaN(max_width)?max_width:0;
        max_height = !isNaN(max_height)?max_height:0;
        // 在这里图片是等比例缩放的,调用方法时填入图片允许的最大宽度或者是最大的高度
        //如果最大宽度为0 则按照最大高度固定,宽度自适应的方式来实现
        //如果是最大高度为0,则按照最大的宽度来实现
        if(max_width==0){
            if (height > max_height) {
                width = Math.round(width *= max_height / height);
                height = max_height;
            }
        }
        if(max_height==0){
            if (width > max_width) {
                height = Math.round(height *= max_width / width);
                width = max_width;
            }
        }
        canvas.width =width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        canvas.width =width;
        canvas.height = height;
        ctx.drawImage(img,0,0, width, height);
        type = type === 'jpg'?"jpeg":type;
        return canvas.toDataURL("image/"+type, 0.7);//这里的0.7值的是图片的质量
  }

在上面的代码中,我们传入的参数主要有image对象,图片类型,图片的最大宽度和最大高度。调用方法时填入图片允许的最大宽度或者是最大的高度,进行等比绘制到canvas中,然后通过toDataURL来转换成base64格式返回,此时的图片就是压缩过后的图片。

创建image对象

上面的示例说了图片压缩的过程,其中有一个参数是image对象,那么这个image对象是如何来的呢。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
selectFileImage(el){
     var reader = new FileReader();
    var file = el.target.files[0]
    var fileName = file.name;
    var fileType = file.name.split(".")[1];
        reader.readAsArrayBuffer(file);

        reader.onload = (ev) => {
            var blob = new Blob([ev.target['result']]);
            window['URL'] = window['URL'] || window['webkitURL'];
            var blobURL = window['URL'].createObjectURL(blob);
            var image = new Image();
            image.src = blobURL;
            image.onload = (e) => {
                var thumb = this.resizeMe(image,fileType, 400, 0);//获得的路径是将图片转换成了base64
                axios.post("http://127.0.0.1:3003/useasync/upload",{file:thumb,fileName:fileName}).then(res => {
                    if (res.data.code == 200) {
                       console.log(res)
                    } else {
                        console.log(res)
                    }
                });
            }
        }
    }

在这里面我使用了一个FileReader对象,FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

当触发input的onChange事件后,可以读取到input中的file文件,于是将此文件读取到缓存当中,当读取完成后,result属性中保存的将是被读取文件的ArrayBuffer数据对象。这里我们可以看一下读取完成后的这个ev到底是个什么东西

我们可以看到这里面loaded和total都表示的是文件的总大小,重要的其实是target和currentTarget,这两个属性其实是一样的,里面包含了读取的fileReader对象,里面的result就是缓存中的数据了,我们通过new 一个Blob对象,将其转换为Blob对象,然后就可以通过url方法来将其转换为可以放到img src中的链接形式了。此时创建image对象,并对其src进行赋值,当image加载完成后,就开始调用压缩方法,传入的image对象就是我们刚才生成的image对象。

当压缩完成后返回的数据就是base64的数据了,我们就可以通过ajax异步来进行上传,在此我采用的是axios进行异步上传,将内容及文件名作为参数传递给后台。

后台接收

在这我才用的示例为nodejs搭建后台来接收图片,这里我们需要一个bodyParser模块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
app.use(bodyParser.json({ limit:'5mb'}));//限制允许提交的大小

将大小限制为5M以内,也就是说通过base64上传的图片大小一定要小于5M才能成功,这个参数我们可以随意更改,按业务需求而定。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
router.post("/upload",function(req,res){
    var imgData = req.body.file;
    var fileName =  req.body.fileName;
    var base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
    //var size = Buffer.byteLength(base64Data,'base64');
    //var dataBuffer = Buffer.alloc(size,base64Data, 'base64');
    var dataBuffer = Buffer.from(base64Data, 'base64');
    fs.writeFile(process.cwd()+"/upload/"+fileName, dataBuffer, function(err) {
        if(err){
            res.json({success:false,errormsg:err});
        }else{
            res.send({success:true,msg:"保存成功!"});
        }
    });
})

接口中我们通过Buffer来将base64转换为buffer,进而保存到服务器本地中,本示例采用的就是将图片保存到服务器本地。如此通过将base64编码图片保存为图片就做完了。

由于压缩采用的是canvas,获取文件等是通过FileReader 对象及Bolb对象,故此方法目前的兼容性最低为IE10,还请酌情使用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
『C语言』系统日期&时间
⒈题目内容 输出系统的日期以及时间。 在本代码当中只有一个main函数将各个控制命令保存在数组当中,然后适用循环语句设置一个死循环。在该循环当中让用户输入命令指令,并且判断用户输入的命令是否和数组当中存储的命令是否相同。如果它们是相同的,则执行相对应的内容。 ⒉题目要求 用户进行某一个操作需要输入一个命令,如果命令输入错误,系统会进行提示。 当用户输入命令字符"0"会显示帮助信息。 当用户输入命令字符"1"会显示系统日期。 当用户输入命令字符"2"会显示系统时间。 当用户输入命令字符"3"会执行退出系统。 ⒊思考问题 一:需要保证程序能够一直执行下去,等待用户的命令防止主函数结束。 二:获取系统日期和系统时间。 ⒋解题思路 结构体struct tm当中的结构成员如下↓
謓泽
2022/12/12
2.7K0
『C语言』系统日期&时间
【C语言】通讯录《动态内存版本》
🚩write in front🚩    🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家博主 & 星级博主~掘金⇿InfoQ~51CTOP创作者~周榜109﹣总榜883⇿全网访问量35w+🏅 🆔本文由 謓泽 原创 CSDN首发🙉如需转载还请通知⚠ 📝个人主页-謓泽的博客_CSDN博客 📃 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏-YY_謓泽的博客-CSDN
謓泽
2022/12/12
5470
【C语言】通讯录《动态内存版本》
【C语言】 扫雷游戏(保姆级的实现过程)
🚀write in front🚀    🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5→周榜31→总榜2513🏅 🆔本文由 謓泽 原创 CSDN首发🐒 如需转载还请通知⚠ 📝个人主页:打打酱油desu-CSDN博客 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏:YY_打打酱油desu-CSDN博客 ✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩 ---- 目录 🚀write in
謓泽
2022/12/12
1.3K0
【C语言】 扫雷游戏(保姆级的实现过程)
【C语言】通讯录《静态内存版本》
Hello🥂謓泽👋多多指教😛 HY点赞👍收藏⭐️留言📝​ ⛳通讯录✔目录 ✨前言   ✨模块化编程  🎓通讯录的逻辑实现  ✨实现通讯录の步骤 🖊创建颜色函数color()  🖊菜单界面函数menu() 🎓通讯录的定义 🖊枚举类型 🎓初始化通讯录 🎓增加通讯录的信息  🎓打印通讯录的信息  🎓删除通讯录的信息  🎓查找通讯录的信息  🎓修改指定通讯录人的信息 🎓排查通讯录当中人员的信息 ✨模块化代码实现 🖊test.c 🖊address_book.c  🖊address_book.h  ✨最后✨ --
謓泽
2022/12/12
9730
【C语言】通讯录《静态内存版本》
C语言坦克大战
//里规格:长39*2=78 (真坐标)(假坐标宽为39) 高39
紫禁玄科
2022/03/24
1.1K0
C语言坦克大战
[C语言] 猜数字小游戏「功能优化」
在C语言中,我们一般使用 <stdlib.h> 头文件中的 rand() 函数来生成随机数,它的用法为:
謓泽
2022/12/12
5920
【C语言】三子棋游戏与多子棋 (保姆级的实现过程)
🚀write in front🚀    🔎大家好,我是泽En,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5→周榜43→总榜3343🏅 🆔本文由 泽En 原创 CSDN首发🐒 如需转载还请通知⚠ 📝个人主页:打打酱油desu-CSDN博客 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏:YY_打打酱油desu-CSDN博客 ✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩 ---- 目录 🚀write in f
謓泽
2022/12/12
3980
【C语言】三子棋游戏与多子棋 (保姆级的实现过程)
【程序源码】VC6下实现C语言贪吃蛇
程序源码 今天是正月初九,相信大家基本上都告别了“新年”这个词,回到了自己正常的轨道,小编也不例外,这不,又开始给大家分享好玩的了,现在过完年刚开工,不宜过度严肃,所以就给大家找了个
编程范 源代码公司
2018/04/16
1.7K0
【程序源码】VC6下实现C语言贪吃蛇
C语言课程设计 — 飞机大战
这个游戏的功能很单一,也就是“飞机大战”,哈哈哈哈。总共只有300多行代码左右,你也可以想想它会有多简陋,把它复制下来编译一下可以直接执行,需要的同学可以自取~
Gorit
2021/12/09
1.2K0
C语言socket实现文件下载[通俗易懂]
是网络编程的作业,我比较菜。。。写到定位输出,做百分比出现了问题,不显示0到100的,直接从0跳到了100。请教了下大佬。改了过来。原来是类型的问题,做出来的运算应该是float,但是我都定义的int,输出也是,大佬指出后,我好尴尬。。。犯了小错误。。。但是在这次过程也学习了一波。要加油了!!!代码写的这么乱!!! 写的是带颜色的版本,,颜色有可能会觉得妖艳,,,好吧。 编译平台是vc++6.0
全栈程序员站长
2022/09/15
1.5K0
C语言socket实现文件下载[通俗易懂]
C语言教你怎么改变字体颜色
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/151557.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/06
3.9K0
C语言教你怎么改变字体颜色
C++项目贪吃蛇游戏笔记-C语言版
#include <stdio.h> #include <Windows.h> #include <stdlib.h> #include <time.h> #include <conio.h> #define ROW 22 //游戏区行数 #define COL 42 //游戏区列数 #define KONG 0 //标记空(什么也没有) #define WALL 1 //标记墙 #define FOOD 2 //标记食物 #define HEAD 3 //标记蛇头 #define BODY 4 //标
CtrlX
2022/09/28
1K0
俄罗斯方块c语言源代码_俄罗斯方块C语言
思路: 1.初始化界面,用一个矩阵来保存界面的每一个位置,包括颜色跟数值,数值用来区分是墙还是方块还是空格,便于运行时的判断。
全栈程序员站长
2022/11/17
3.6K0
俄罗斯方块c语言源代码_俄罗斯方块C语言
【C语言】贪吃蛇游戏的实现(一)[通俗易懂]
(注意:本代码是在VC++6.0环境下编译的,在其他环境如codeblocks下运行可能会产生意想不到的问题,请尽量使用VC。至于为什么要使用VC编译,哦,我亲爱的朋友,这只有上帝才知道)
全栈程序员站长
2022/09/05
1.3K0
【C语言】贪吃蛇游戏的实现(一)[通俗易懂]
模拟猜单词游戏
模拟实现猜单词游戏,纯模拟,不涉及图形界面,注释很详细,虽然本人代码写得丑,但是希望可以给大家提供帮助 #include<algorithm> #include<cstdlib> #include<cstring> #include<fstream> #include<ctime> #include<cmath> #include<iomanip> #include<windows.h> using namespace std; int times=10;//全局变量,默认猜测次数 typedef s
triplebee
2018/01/12
6700
c语言实现图书管理系统创新_c语言图书管理系统源代码
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/18
1.9K0
c程序设计,贪吃蛇程序是什么_C语言编写贪吃蛇
思路:一行一行的输出,输出完一行就换行继续输出,直到输出完边框部分。 第一步:先输出第一行,输完第一行进行换行。(这里@代表◼)
全栈程序员站长
2022/11/17
2.1K0
C语言实现简单贪吃蛇代码
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/141348.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/01
2.4K0
C语言实现简单贪吃蛇代码
贪吃蛇(C语言实现)
贪吃蛇游戏当中蛇的移动速度可以进行调整,动图当中把速度调得较慢(速度太快导致动图上蛇身显示不全),下面给出的代码当中将蛇的速度调整到了合适的位置,大家可以试试。
全栈程序员站长
2022/08/24
2.2K0
贪吃蛇(C语言实现)
C语言怎么改变窗口的字体颜色和背景颜色?
如果学C语言久了,难免会对弹出的黑窗口感到厌烦,那这时候如果能改一下黑窗口的背景颜色和字体颜色,也许会给自己一个好一点的心情。废话不多说,现在开始教你怎么简单地改变窗口的字体颜色和背景颜色。
全栈程序员站长
2022/09/06
6.4K0
C语言怎么改变窗口的字体颜色和背景颜色?
推荐阅读
相关推荐
『C语言』系统日期&时间
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验