手写压缩图片

170 阅读5分钟

文心一言回答:

要在Vue中手写图片压缩,你可以使用HTML5的Canvas API和File API来实现。以下是一个简单的示例代码,它可以将上传的图片进行压缩并显示在页面上:

<template>
  <div>
    <input type="file" @change="handleFileChange" />
    <img v-if="compressedImage" :src="compressedImage" alt="Compressed Image" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      compressedImage: null,
    };
  },
  methods: {
    handleFileChange(event) {
      const file = event.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (e) => {
          const img = new Image();
          img.onload = () => {
            const canvas = document.createElement("canvas");
            const ctx = canvas.getContext("2d");
            const MAX_WIDTH = 800; // 设置压缩后的最大宽度
            let width = img.width;
            let height = img.height;
            if (width > height) {
              if (width > MAX_WIDTH) {
                height *= MAX_WIDTH / width;
                width = MAX_WIDTH;
              }
            } else {
              if (height > MAX_WIDTH) {
                width *= MAX_WIDTH / height;
                height = MAX_WIDTH;
              }
            }
            canvas.width = width;
            canvas.height = height;
            ctx.drawImage(img, 0, 0, width, height);
            this.compressedImage = canvas.toDataURL("image/jpeg", 0.8); // 将canvas转换为图片数据URL,第二个参数为图片质量,范围为0-1
          };
          img.src = e.target.result;
        };
        reader.readAsDataURL(file);
      }
    },
  },
};
</script>

在上面的代码中,我们首先定义了一个文件输入框和一个用于显示压缩后图片的img元素。当用户选择文件后,handleFileChange方法会被调用。在该方法中,我们首先通过FileReader对象读取文件内容,并将其转换为DataURL。然后,我们创建一个Image对象,并设置其src属性为DataURL,以便在图片加载完成后进行压缩。

在图片加载完成后,我们创建一个canvas元素,并设置其宽度和高度为压缩后的尺寸。然后,我们使用drawImage方法将原始图片绘制到canvas上。最后,我们使用canvas.toDataURL方法将canvas转换为图片数据URL,并将其赋值给compressedImage数据属性,以便在img元素中显示。

canvas.toDataURL方法中,第一个参数指定输出图片的格式,第二个参数指定图片质量,范围为0-1。在这个例子中,我们将图片质量设置为0.8。

请注意,这只是一个简单的示例代码,它只支持JPEG格式的图片压缩。如果你需要支持其他格式或更高级的压缩选项,你可能需要使用第三方库,如compressorjs等。

HTML写法:

要在HTML和TypeScript中实现图片压缩,你可以使用Web API中的CanvasFile API,结合TypeScript的类型安全特性来编写代码。下面是一个简单的示例,展示了如何在前端实现图片压缩:

首先,你需要在HTML中创建一个文件输入元素来接收用户上传的图片:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片压缩</title>
</head>
<body>
<input type="file" id="imageUpload" accept="image/*">
<button onclick="compressImage()">压缩图片</button>
<div id="compressedImageContainer"></div>

<script src="compress.ts"></script>
</body>
</html>

然后,在TypeScript文件(比如compress.ts)中,你可以编写压缩图片的逻辑:

const imageUpload = document.getElementById('imageUpload') as HTMLInputElement;
const compressedImageContainer = document.getElementById('compressedImageContainer') as HTMLElement;

function compressImage() {
  const file = imageUpload.files[0];
  if (!file) {
    alert('请选择一个图片文件');
    return;
  }

  const reader = new FileReader();
  reader.onload = (event) => {
    const img = new Image();
    img.onload = () => {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');

      // 设置压缩后的图片尺寸
      const MAX_WIDTH = 800;
      const MAX_HEIGHT = 800;
      let width = img.width;
      let height = img.height;

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
      }

      canvas.width = width;
      canvas.height = height;

      // 绘制图片到canvas
      ctx.drawImage(img, 0, 0, width, height);

      // 将canvas转换为图片数据URL
      const compressedDataUrl = canvas.toDataURL('image/jpeg', 0.8); // 第二个参数为图片质量,范围0-1

      // 显示压缩后的图片
      const compressedImageElement = document.createElement('img');
      compressedImageElement.src = compressedDataUrl;
      compressedImageContainer.appendChild(compressedImageElement);
    };
    img.src = event.target.result;
  };
  reader.readAsDataURL(file);
}

在这个示例中,我们首先通过FileReader读取用户选择的图片文件,并将其转换为DataURL。然后,我们创建一个新的Image对象,并设置其src属性为读取到的DataURL。一旦图片加载完成,我们创建一个canvas元素,并根据最大宽度和高度调整图片的尺寸。接着,我们将原始图片绘制到canvas上,并使用canvas.toDataURL方法将canvas内容转换为压缩后的图片数据URL。最后,我们创建一个新的img元素,将其src属性设置为压缩后的数据URL,并将其添加到页面上。

注意,canvas.toDataURL方法的第二个参数是图片质量,范围从0(最差质量,最小文件大小)到1(最佳质量,最大文件大小)。在这个例子中,我们将其设置为0.8以获取适当的压缩效果。

确保你的开发环境已经配置好TypeScript,并且你的HTML文件能够正确地引用TypeScript编译后的JavaScript文件。你可能需要设置一个构建过程,将TypeScript代码编译为浏览器可以理解的JavaScript代码。

生成tsconfig.json

是否已经安装了typescript

npm ls -g typescript

报错

image.png

1、查看本机TS版本 npm view typescript version

image.png

2、查看本地是否安装 npm ls typescript

image.png

首先全局安装typescript

npm install typescript -g

安装上Typescript后,查看是否安装成功,在黑窗口输入  tsc -v ,如果出现一下提示则安装成功:

image.png

在项目目录下执行

tsc --init

目录

image.png

index.html

ts类型: HTMLInputElement 这种ts类型还有那些

blog.csdn.net/m0_57033755…

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="file" type="file">
    <script src="./index.js"></script>
</body>
</html>

index.ts


const file = document.querySelector('#file') as HTMLInputElement
file.addEventListener('change', (e) => {
    console.log(e);
    const target = e.target as HTMLInputElement
    const fileObj = target.files?.[0]
    console.log(fileObj);
    
})


tsc -w 实时去编译我们的文件

image.png

接下来就是把这个file转成base64 去创建一个图片 再把图片放到canvas里面就可以调整大小了

file转成base64 用什么转?

image.png

创建类


// compress压缩的意思
interface Options {
    file: File,
    quality?:number//调整图片大小质量的
}

class CompressImg  {
    options:Options
    fileReader = new FileReader() //客户端(浏览器)异步读取文件内容的 JavaScript 内置对象
    constructor(options:Options) {
        this.options = options
        this.createBase64()
    }
    createBase64(){
        this.fileReader.readAsDataURL(this.options.file);//返回:同时 result 属性将包含一个data:URL 格式的字符串(base64 编码)以表示所读取文件的内容。
        this.fileReader.onload =  (e) => {
          console.log(e.target?.result);
          
        };
    }
}

const file = document.querySelector('#file') as HTMLInputElement
file.addEventListener('change', (e) => {
    console.log(e);
    const target = e.target as HTMLInputElement
    const fileObj = target.files?.[0]
    console.log(fileObj);

    if (fileObj) {
        new CompressImg({
            file:fileObj
        })
    }    
})

image.png

image.png

canvas

image.png

接下来就是 获取宽高

image.png

代码

// compress压缩的意思
interface Options {
    file: File,
    quality?: number,//调整图片大小质量的
    success?: (base64: string) => void
}

class CompressImg {
 
    options: Options
    fileReader = new FileReader() //客户端(浏览器)异步读取文件内容的 JavaScript 内置对象
    constructor(options: Options) {
        this.options = options
        this.createBase64()
    }

    createBase64() {
        this.fileReader.onload = (e) => {
            //未压缩之前 9.1m 4.1m
            this.compress(e.target?.result as string)
        };
        this.fileReader.readAsDataURL(this.options.file);//返回:同时 result 属性将包含一个data:URL 格式的字符串(base64 编码)以表示所读取文件的内容。
    }

    compress(url: string) {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')//可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
        const img = new Image()
        img.src = url
        img.onload = () => {
            // 解决图片不出来 canvas需要加width 、height
            canvas.width = img.width
            canvas.height = img.height
            ctx?.drawImage(img, 0, 0, img.width, img.height)
            const base64 = canvas.toDataURL(this.options.file.type, this.options.file)
            this.options.success?.(base64)
        }
    }
}

const file = document.querySelector('#file') as HTMLInputElement
file.addEventListener('change', (e) => {
    const target = e.target as HTMLInputElement
    const fileObj = target.files?.[0]
    if (fileObj) {
        new CompressImg({
            file: fileObj,
            quality: 0.5,
            success: (base64) => {
                document.body.innerHTML = `<img src="${base64}">`
            }
        })
    }
})

参考

FileReader.readAsDataURL()

developer.mozilla.org/zh-CN/docs/…

canvas

blog.csdn.net/monparadis/…

www.runoob.com/tags/canvas…

developer.mozilla.org/zh-CN/docs/…