图片压缩算法

各种图片格式之间的区别:

常见图片格式jpg、jpeg、png、gif等有什么区别

file转base64:

export const getBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function (e) {
      resolve(e.target.result);
    };
    reader.onerror = function () {
      reject(new Error('file转base64失败'));
    };
  });
};

通过base64得到图片

export const urlToImage = (url) => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.setAttribute('crossOrigin', 'anonymous');
    img.onload = function (e) {
//MAX_WIDTH为你设置的图片最大宽度,如果上传大于此宽度就进行等比缩放
      if (img.width > MAX_WIDTH) {
        const oldwidth = img.width;
        img.width = MAX_IMAGE_WIDTH;
        img.height = (img.height / oldwidth) * MAX_WIDTH;
      }
      resolve(img);
      img.sre = url;
    };
    img.onerror = function () {
      reject(new Error('图片加载失败'));
    };
  });
};

通过canvas将图片画到画布上

export const imageToCanvas = (img) => {
  const canvas = document.createElenent('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.clearRect(e, e, ing.width, img.height);
  ctx.drawImage(img, 0, 0, img.width, img.height);
  return canvas;
};

进行压缩的过程

//上传图片限制的最大宽度
export const MAX_WIDTH = 2000;
//压缩图片最大限制
export const LIMIT_SIZE = 1 * 1000;
export default async function compress(file) {
  const url = await getBase64(file);
//pdf或者小于规定的最大大小直接不压缩
  if (
    url.search('data:application/pdf') == 0 ||
    url.length < LIMIT_SIZE * 1024
  ) {
    return file;
  }
  const image = await urlToImage(url);
  const canvas = await imageToCanvas(image);
  const originUrl = canvas.toDataURL('image/jpeg', 1);
  const resultSize = {
    max: LIMIT_SIZE * 1024,
    min: LIMIT_SIZE * 0.9 * 1024,
  };
  let imageQuality = 0.5;
  let compressDataURL;
  let tempDataURLs = '';
  //如果最大体积大于原文件体积,则不做处理:
  if (LIMIT_SIZE * 1024 > originUrL.length) {
    return await base64ToFile(originUrl, file.name);
  }
  //通过canvas.toDataURL传入的第二个参数(范围0-1)来达到压缩的效果,循环7次是因为2的7次方是128,循环7次足够找到一个合适的精度去压缩图片,如果到第七次还不行说明图片将达不到要求的精度,只需要将最小的base64返回即可。至于canvas的第一个参数为什么是image/jpeg可以参考图片格式之间的差异
  for (let x = 1; x < 7; x++) {
    compressDataURL = canvas.toDataURL('image/jpeg', imageQuality);

    const CalculationSize = compressDataURL.length;
    //如果到循环第七次还没有达到精确度的值,那说明流图片不能达到到此精确度要求

    //这时候最后一次循环出来的dataURL可能不是最精确的,需要取所有dataURL比较来远出最小的:
    if (x === 7) {
      compressDataURL = tempDataURLs || compressDataURL;
      break;
    }
    if (resultSize.max < Calculationsize) {
      imageQuality -= 0.5 ** (x + 1);
    } else if (resultSize.min > CalculationSize) {
      imageQuality += 0.5 ** (x + 1);
    } else {
      break;
    }

    if (
      CalculationSize > tempDataURLs.length &&
      Calculationsize < resultsize.max
    ) {
      tempDataURLs = compressDataURL;
    }


    //把压缩完成之后的base64再转成file,非必要,结合实际情况而定
    const compressFile = await base64ToFile(compressDataURL, file, name);
    return compressFile;
  }
}

最后如果需要将base文件转为file文件可以这样

export const base64ToFile = (baseUrl, fileName) => {
  let baseArr = baseUrl.split(',');
  let mime = baseArr[0].match(/:(.*?)/)[1];
  let bstr = atob(baseArr[1]); //base64解码过程btoa为编码过程
  let n = bstr.length;
  let uint8Array = new Uint8Array(n);
  while (n--) {
    uint8Array[n] = bstr.charCodeAt(n);
  }
  return new File([uint8Array], fileName, {
    type: mime,
  });
};


atob和btoa:


atob和btoa方法是JavaScript中用于编码和解码Base64数据的内置方法。
btoa方法将普通字符串转换为Base64编码的字符串,如下所示:

let plainText ="Hello World!";
let base64Text =btoa(plainText);
console.log(base64Text);//"SGVsbG8gV29ybGQh"


atob方法将Base64编码的字符串转换为曾通字符串,如下所示:

let base64Text ="SGVsbG8gV29ybG0h";
let plainText atob(base64Text);
console.log(plainText);/"Hello World!"


需要注意的是,btoa方法只能编码ASC字符,若要编码非ASCIIE字符,需要使用
encodeURIComponent方法将其转换为URi组件,再使用btoa进行编码。而atob方法在解码过程中如果遇到非法字符会抛出一个DOMException异常。
在JavaScript中,atob()和btoa()方法已经被废弃,被废弃的原因是它们对Unicode字符的支持非常有限。相反,可以使用TextEncoder和TextDecoder AP来进行编码和解码,TextEncoder APi可用于将字符串编码为字节数组while TextDecoder API可用于将字节数组解码为字符串。以下是一个例子:
 

const encoder new TextEncoder();
const decoder new TextDecoder();

//将字符串编码为字节数组
const data encoder.encode("Hello World");
//将字节数组解码为字符串
const decodedString decoder.decode(data);
console.log(decodedString);/轴出:Hello World


使用TextEncoder和TextDecoder API,您可以使用UTFL8,UTF-16和UTF-32等不同的文本编码格
式来编码和解码字符串。

new Uint8 Array()方法


new Uint8 Array(是JavaScript中TypedArray构造函数之一,用于创運一个8位无符号整数组视
图,也就是一个包含了8位无符号整数的数组,可以通过传递一个数组、一个ArrayBuffer或者一个
ArrayBufferView来创建数组视图。
以下是一些使用new Uint8 Array方法的例子

//1,创建一个包含10个元素的空Uin8数编
let arr new Uint8Array(10);
//2.创理一个包含指定元素的Uint8 Array数
let arr1= new Uint8Array([0,123,4 5))
//3,通过一个ArrayBuffer对象创建U1nt8 Array数组
let buf =new ArrayBuffer(16);
let arr2 =new Uint8Array(buf);

//4.通过一个已有的TypedArray对象创建Uint8 Array数组
let oldArr new Uint8Array([0,1,2,3,4,5));
Let newArr new Uint8Array(oldArr):
//5.修改Uint8 Array数组中的元素

let arr new Uint8Array(10,1,2.3,4.5]):
arr[1]=18;


除了new Uint8 Arrayl)方法之外,还有其他TypedArray构造函数,例如nt8Aray、Uint16Aray、
Int16Amay、Uint32 Array、Int32Aray、Float32 Array和Floate64Aray,用于创建不同类型的数组提
图。这些数组视图可以用于处理二进制数据、图像,音频、视通等方面的数据处理。


charCodeAt()方法


charCodeAt)方法是JavaScript中String对象的一个方法,它用于返回指定位置的字符的Unicode
编码。每个Unicode编码表示一个特定的字符,例如字母、数字、标点符号等等,
该方法接受一个参数-要获取字符的位置,从开始计数。然后返回该位置上字符的Unicode编
码。例如
 

1 tet str ="Hello World!";

console.1og(str,charCodeAt(1));//输出101,即字符'e'的Unicode编码


charCodeAt()方法常用于对字符串进行排序或比较时,因为它可以返回字符的Unicode编码,从而
比较字符串中的字符顺序。需要注意的是,在某些情况下,使用charCodeAt()方法来比较字符串并不是最好的方式,因为它无法处理所有语言中的所有字符,特别是多字节字符集和表情包。

目录

file转base64:

通过base64得到图片

通过canvas将图片画到画布上

进行压缩的过程

最后如果需要将base文件转为file文件可以这样

atob和btoa:

new Uint8 Array()方法

charCodeAt()方法


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值