关于html5:h5中使用javascript在客户端对图片进行压缩和尺寸处理附ts代码

有时候咱们有这样的需要,就是对前端选中的图片进行压缩解决。
这样解决的起因可能是。

  1. 缩小带宽占用率,提高效率。
  2. 对图片进行裁剪合乎上传需要。(当初手机拍照分辨率很高,间接拿来用比拟大。)

前端对图片进行压缩次要应用到的API有:

  1. Canvas
  2. Image
  3. File
  4. Blob
  5. FileReader

如图,设置三个办法

  1. toImage
  2. toCanvas
  3. toFile
/**次要办法*/
async function miniImage(params:{
    url?:string,
    file?:File,
    quality?:number,
    fileName?:string,
    size?:{width:number,height:number},
    fitLength?:number
      }={quality:1,fileName:'压缩图片'}
  ){
  console.assert(params.url||params.file,'url和file必填其一')
  console.assert(params.quality<=1&&params.quality>0,'quality的取值范畴是0-1')
  const img = await toImage({file:params.file,url:params.url})
  const canvas = toCanvas({img,size:params.size,fitLength:params.fitLength})
  return await toFile(canvas,{quality:params.quality,fileName:params.fileName})
}

toImage办法

该办法次要是应用Image以及File、FileReader来进行转换,传参如果是file,则应用后者,如果只是url,则间接应用Image。
其中留神FilerReader的用法,在h5的开发中很多中央都会应用到。

/**转换成图片 */
async function toImage (params: {file?: File, url?: string}): Promise<HTMLImageElement> {
  return new Promise((reso, rej) => {

    const {file, url} = params
    const img = new Image()
    img.onload = () => {
      return reso(img)
    }
    // 文件形式
    if (file) {
      const reader = new FileReader()
      reader.onload = (e) => {
        img.setAttribute('src', e.target?.result as string)
      }
      reader.readAsDataURL(file)
    } else if (url) {
      img.setAttribute('src', url)
    } else {
      console.error(`解析图片出错`)
    }
  })
}

toCanvas办法

该办法次要是应用CanvasRenderingContext2D的drawImage办法。
该办法的入参定义:drawImage(HTMLImageElement,dx,dy,dw,dh)
即传入办法,而后绘制图片,管制绘制地位,以及绘制的宽高。
此外咱们还须要做更多的兼容,减少入参,管制图片的尺寸。代码如下。

/**转换成canvas */
function toCanvas (img: HTMLImageElement, options?: {size?: {width: number, height: number}, maxLength?: number}) {
  const canvas = document.createElement('canvas')
  let {size, maxLength} = options ?? {}
  let {height, width} = img
  if (size || maxLength) {
    if ((!size?.height || !size.width) && !maxLength) maxLength = size?.height ?? size?.width
    // 设置长度并去适应
    if (maxLength) {
      let maxlen = Math.max(height, width)
      let rate = maxLength / maxlen
      height = maxlen === height ? maxLength : height * rate
      width = maxlen === width ? maxLength : width * rate
    } else if (size) {
      // 设置了尺寸
      height = size.height
      width = size.width
    }
  }
  canvas.height = height
  canvas.width = width
  const ctv = canvas.getContext('2d')
  ctv?.drawImage(img, 0, 0, width, height)
  return canvas
}

toFile 办法

最初一步,把图片转成咱们须要的文件用以上传。
该步骤次要是应用canvas的toBlob办法,而后通过File来生成新的file。
注:在js中,一个文件根本就是Blob加上name。
具体代码如下:

/**canvas转文件 */
function canvasToFile (canvas: HTMLCanvasElement, options: {fileName?: string, quality?: number} = {quality: 1, fileName: '图片'}): Promise<File> {
  return new Promise((reso, rej) => {
    canvas.toBlob((blob) => {
      const file = new File([ blob as Blob ], options!.fileName as string, {
        type: 'image/png',
      })
      reso(file)
    }, '', options.quality)
  })
}

miniImageByUrl办法

最初咱们联合下面在写一个办法用来预览,把生成的canvas间接转成dataUrl,在页面展现。

/**解决图片压缩,并且转成url */
export const imageMinByUrl = async (
  params: {
    file?: File
    url?: string
    quality?: number
    maxLength?: number,
    size?: {height: number, width: number},
  } = {quality: 1}
) => {
  console.assert(params.file || params.url, '必须存在file或者url入参')
  const img = await toImage({file: params.file, url: params.url})
  const canvas = toCanvas(img, {size: params.size, maxLength: params.maxLength})
  return canvas.toDataURL('image/png', params.quality)
}

npm中能够通过cdd-lib间接应用,该库提供了imageMinByUrlimageMin办法。

参考:

  1. <<How to resize image in Javascript?>>

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据