js使用canvas实现图片压缩,上传服务器

实现思路

  1. 使用input获取本地文件
  2. 使用FileReader把图片转为base64格式
  3. 使用html5的canvas压缩图片(canvas只能处理base64格式的图片)
  4. 将压缩后的base64 数据放到input中提交
demo
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>压缩图片demo</title>
</head>
<body>
    <img id="img" src="">
    <input id="file" type="file" onchange="compress()">
</body>
<script>

// 对图片进行压缩
function compress() { 
    let fileObj = document.getElementById('file').files[0] //上传文件的对象
    let reader = new FileReader()
    reader.readAsDataURL(fileObj)
    reader.onload = function(e) {
        let image = new Image() //新建一个img标签(还没嵌入DOM节点)
        image.src = e.target.result
        image.onload = function() {
            let canvas = document.createElement('canvas'), 
            context = canvas.getContext('2d'),
            imageWidth = image.width / 2,    //压缩后图片的大小
            imageHeight = image.height / 2,
            data = ''

            canvas.width = imageWidth
            canvas.height = imageHeight

            context.drawImage(image, 0, 0, imageWidth, imageHeight)
            data = canvas.toDataURL('image/jpeg')

            //压缩完成  这里的data就是我们需要压缩图片数据
            document.getElementById('img').src = data
        }
    }
}
</script>
</html>
等比压缩判断
  var MAX_HEIGHT = 1000;
  if (image.height > MAX_HEIGHT && image.height >= image.width) {
            // 宽度等比例缩放 *=
            image.width *= MAX_HEIGHT / image.height;
            image.height = MAX_HEIGHT;
        }
       //考录到用户上传的有可能是横屏图片同样过滤下宽度的图片。
        if (image.width > MAX_HEIGHT && image.width > image.height) {
            // 宽度等比例缩放 *=
            image.height *= MAX_HEIGHT / image.width;
            image.width = MAX_HEIGHT;
        }

如果要写兼容判断

//第一种方法判断
if(window.FileReader) {  
    var fr = new FileReader();  
    // add your code here  
} else {  
    alert("Not supported by your browser!");  
}
//第二种方法判断
if(typeof FileReader==='undefined'){
    alert('您的浏览器不支持图片上传,请升级您的浏览器');
      return false;
 }
  • 测试结果说明:Google,FF,IE都支持FileReader
  • 但是IE9及以下浏览器不支持FileReader

为什么要使用到 image.onload(onload:等待图片加载完成会自动触发的方法),因为当image的src发生改变,浏览器就会跑去加载这个src里的资源。这个操作是异步的,就是说,js不会傻傻地在原地等待图片的加载,而是继续读代码,直到图片加载完成,触发onload事件,js才会回来执行onload里面的内容。

FileReader API

FileReader实例拥有五种个方法,其中三个是用来读取文件,另一个是用来中断读取的。需要注意的是,无论读取成功或是失败,方法并不会返回读取结果,这一结果(储存在result属性中)要用FileReader处理事件去获取;
abort,中断读取
readAsBinaryString,将文件转化为二进制码(可以读取任何类型文件)
readAsDataURL,读取文件内容,结果用data:url的字符串形式表示
readAsText,将文件读取为文本
readAsArrayBuffer,方法将读取一个Blob对象或者File对象,并产生一个ArrayBuffer对象。ArrayBuffer对象是一个固定长度的二进制数据缓冲。它们在处理文件可以派上用场(如将JPEG转换为PNG)。
readAsText:该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。
readAsText(file,encoding)可按指定编码方式读取文件,但读取文件的单位是字符,故对于文本文件,只要按规定的编码方式读取即可;而对于媒体文件(图片、音频、视频),其内部组成并不是按字符排列,故采用readAsText读取,会产生乱码,因此不是最理想的读取文件的方式。
readAsBinaryString:该方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。
readAsDataURL:这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 Data URL,Data URL是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。
控制台为当前所传文件的base64编码表示。由于媒体文件的src属性,可以通过采用网络地址或base64的方式显示,因此我们可以利用readAsDataURL实现对图片的预览(即img src=data,这个data就是readAsDataURL处理后的结果,直接可以用来显示)。
FileReader 事件
FileReader.onabort,处理abort事件。该事件在读取操作被中断时触发。
FileReader.onerror,处理error事件。该事件在读取操作发生错误时触发。
FileReader.onload,处理load事件。该事件在读取操作完成时触发。
FileReader.onloadstart,处理loadstart事件。该事件在读取操作开始时触发。
FileReader.onloadend,处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。
FileReader.onprogress,处理progress事件。该事件在读取Blob时触发。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。