【canvas】 使用canvas压缩图片大小

------------恢复内容开始------------

由于各种大大小小的原因,自己最近经历了一些面试,其中有一个面试题是这样的,使用canvas怎样压缩图片大小

这道题给我问蒙了,因为我没用过canvas压缩图片

回去查资料,发现手机端在上传图片的时候,调起相机拍照的时候超过2m了,所以用到canvas压缩,优化用户体验

解决方法:

1. 将图片的file文件转成baseURL

2. 创建一个image表情去接受文件获取图片的宽高和比例。

3. 创建canvas画布设置画布的大小。

4. 将图片绘制到canvas上面。

5. 对canvas进行压缩处理,获取新的baseURL

6. 将baseURL转化回文件

1.

/**
* @param {二进制文件流} file
* @param {回调函数,返回base64} fn
*/
function changeFileToBaseURL(file,fn){
  // 创建读取文件对象
      var fileReader = new FileReader();
      //如果file没定义返回null
      if(file == undefined) return fn(null);
      // 读取file文件,得到的结果为base64位
      fileReader.readAsDataURL(file);
      fileReader.onload = function(){
        // 把读取到的base64
        var imgBase64Data = this.result;
        fn(imgBase64Data);
      }
    }

2.
/**
 * 将base64转换为文件
 * @param {baseURL} dataurl
 * @param {文件名称} filename
 * @return {文件二进制流}
*/
function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(‘,‘), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
 }

3.
/**
* canvas压缩图片
* @param {参数obj} param
* @param {文件二进制流} param.file 必传
* @param {目标压缩大小} param.targetSize 不传初始赋值-1
* @param {输出图片宽度} param.width 不传初始赋值-1,等比缩放不用传高度
* @param {输出图片名称} param.fileName 不传初始赋值image
* @param {压缩图片程度} param.quality 不传初始赋值0.92。值范围0~1
* @param {回调函数} param.succ 必传
*/
function pressImg(param){
  //如果没有回调函数就不执行
  if(param && param.succ){
     //如果file没定义返回null
     if(param.file == undefined) return param.succ(null);
     //给参数附初始值
     param.targetSize = param.hasOwnProperty("targetSize") ? param.targetSize : -1;
     param.width = param.hasOwnProperty("width") ? param.width : -1;
     param.fileName = param.hasOwnProperty("fileName") ? param.fileName: "image";
     param.quality = param.hasOwnProperty("quality") ? param.quality : 0.92;
     var _this = this;
     // 得到文件类型
     var fileType = param.file.type;
     // console.log(fileType) //image/jpeg
     if(fileType.indexOf("image") == -1){
       console.log(‘请选择图片文件^_^‘);
       return param.succ(null);
     }
     //如果当前size比目标size小,直接输出
     var size = param.file.size;
     if(param.targetSize > size){
       return param.succ(param.file);
     }
     // 读取file文件,得到的结果为base64位
     changeFileToBaseURL(param.file,function(base64){
       if(base64){
         var image = new Image();
         image.src = base64;
         image.onload = function(){
           // 获得长宽比例
           var scale = this.width / this.height;
           // console.log(scale);
           //创建一个canvas
           var canvas = document.createElement(‘canvas‘);
           //获取上下文
           var context = canvas.getContext(‘2d‘);
           //获取压缩后的图片宽度,如果width为-1,默认原图宽度
           canvas.width = param.width == -1 ? this.width : param.width;
           //获取压缩后的图片高度,如果width为-1,默认原图高度
           canvas.height = param.width == -1 ? this.height : parseInt(param.width / scale);
           //把图片绘制到canvas上面
           context.drawImage(image, 0, 0, canvas.width, canvas.height);
           //压缩图片,获取到新的base64Url
           var newImageData = canvas.toDataURL(fileType,param.quality);
           //将base64转化成文件流
           var resultFile = dataURLtoFile(newImageData,param.fileName);
           //判断如果targetSize有限制且压缩后的图片大小比目标大小大,就弹出错误
           if(param.targetSize != -1 && param.targetSize < resultFile.size){
             console.log("图片上传尺寸太大,请重新上传^_^");
             param.succ(null);
           }else{
             //返回文件流
             param.succ(resultFile);
           }
         }
       }
     });
   }
 }

------------恢复内容结束------------

原文地址:https://www.cnblogs.com/teemor/p/12580510.html

时间: 2024-10-06 22:49:05

【canvas】 使用canvas压缩图片大小的相关文章

怎样压缩图片大小

现在从事自媒体工作的人是越来越多了,大多数自媒体人在写文章的时候都会配图,但是有的平台只给上传多少k以内的图片,很多时候我们上传的数码设备拍摄的图片就会遇到经常上传不了的情况,这是因为在高像素下拍摄的图片大小远超过平台可以容忍的大小,这个时候我们就要选择去压缩图片,那如何高效率的压缩图片大小呢,今天小编就给大家介绍一下.第一步.打开电脑进入浏览器搜索迅捷在线压缩进入首页.第二步.进入压缩网站后,在下方会看的三个压缩选项,选择我们所需要的在线图片压缩.第三步.点进在线图片压缩后,在中间可选择点击添

如何压缩图片大小不改变像素

压缩图片实际上就是将图片的体积在一定的条件下进行压缩变小,这一过程一般都会对图片本身带来一定的改变,选择压缩的方法或者是工具的时候一定要考虑效果,有些压缩之后的图片已经完全不是之前的样子了,但是想要完全不改变像素也是不太实际的,下面小编为大家介绍一个图片压缩的软件,告诉你如何压缩图片大小不改变像素!具体方法如下:在线进行图片的压缩1:在浏览器中搜索在线图片压缩,打开网站之后点击在线图片压缩就可以进入操作界面. 2:添加要进行压缩的图片,点击或者拖拽都可以添加图片. 3:点击开始压缩的按钮,系统会

压缩图片大小的方法介绍

上传图片的时候我们会发现很多网站对图片大小的限制一般都是最大不超过20k,可能这是一个最佳的大小吧,既然规定了,就只能按照规定的大小进行上传,不过超过20k的图片那真的数不胜数了,遇到过大的图片只能进行大小的压缩,下面是压缩图片大小的方法介绍,不知道方法的话可以来学习一下!具体方法如下:图片压缩软件请添加链接描述可以压缩图片1:打开压缩软件,点击图片压缩就好. 2:添加要进行压缩的图片,点击添加文件或者添加文件夹的按钮就可以选择文件,一次可以同时压缩很多张图片.3:在添加文件下面有输出格式以及压

iOS一行代码压缩图片大小

现在基本所有应用都与图片相关联,这就必然涉及到上传下载图片,而用户的流量又迟迟没有被解放,因此图片就不能太大,我们知道iPhone一张照片动辄几M,如果都传原图那流量就会爆炸,粗暴地缩小又会影响图片的分辨率.那有没有办法在保持一定分辨率的情况下压缩图片呢?有的,而且非常简单,一行代码搞定,是苹果自带的压缩函数: UIImageJPEGRepresentation UIImagePNGRepresentation 这两个函数都是iOS自带的图片压缩工具.一个是压成JPEG格式,一个是压成PNG格式

压缩图片大小至指定Kb以下

像PS,QQ影像等都有该功能,将图片大小压缩至指定kb以下. 我也来山寨一把,到目前为止,控制图片的大小,平时的解决方案通过分辨率和质量来控制的. 假定最后压缩的大小是100kb,那么在保证不大于100kb的前提下,图片质量尽可能高.图片质量越高,图片占用大小就越大.但是大小与质量的关系,没有一个固定的公式,如y= nx 之类的,而且我也试过将win7系统的图片收藏夹的图,每一张保存10次,从质量为10,递增到100,发现只能得出之前的结论,图片质量高,占用大小就大. 既然这样,那只能找到满足1

java上传图片并压缩图片大小

Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生成处理后的图片,且允许微调图片的生成方式,同时保持了需要写入的最低限度的代码量.还支持对一个目录的所有图片进行批量处理操作.支持的处理操作:图片缩放,区域裁剪,水印,旋转,保持比例.另外值得一提的是,Thumbnailator至今仍不断更新,怎么样,感觉很有保障吧!Thumbnailator官网:h

JS使用canvas操作、压缩图片

1.使用input标签添加图片文件. <input type="file" name="upload_photo" id="upload_photo" accept="image/jpg,image/jpeg,image/png" value='upload now'>//使用accept限定文件类型 2.监听input的change事件,获取文件内容 $('#upload_photo').on('change',

iOS压缩图片大小

最近碰到一个比较愚蠢的问题,项目中做的拍照或者从相册选择图片上传时,没有经过处理,直接把原图上传了,导致在列表中看的时候,明明是小图片流量却要爆炸了,想想iphone拍出照片大小可都是以M为单位的.所以赶紧做了下压缩处理再上传.为了方便根据不同压缩需求调用,这里采用调用可修改参数的方法的做法,更加灵活一点.调用的方法如下: //图片伸缩到指定大小 - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize forImage:(U

android 压缩图片大小,防止OOM

android开发中,图片的处理是非常普遍的,经常是需要将用户选择的图片上传到服务器,但是现在手机的分辨率越来越好了,随便一张照片都是2M或以上,如果直接显示到ImageView中,是会出现OOM的,上传到如服务器也会占用大量的流量,用户体验肯定不好了! 下面自己实现了图片的显示以及压缩功能,主要代码是从Volley的ImageRequest中copy过来,作为工具类方便以后图片处理 package com.img.util; import java.io.File; import java.i