引言
一、技术背景与需求分析
1.1 技术栈选择
- Vue3:作为新一代的前端框架,Vue3提供了更高效的响应式系统和更灵活的Composition API。
- TypeScript:强类型语言,有助于提高代码的可维护性和可读性。
- Canvas:HTML5提供的绘图API,可用于图片处理和压缩。
1.2 需求背景
- 用户体验差:加载时间长,页面渲染慢。
- 服务器压力大:存储成本高,处理图片耗时。
- 流量消耗大:对移动用户尤为不利。
二、图片压缩原理与实现
2.1 图片压缩类型
2.2 压缩实现步骤
- 获取图片文件:通过文件选择器获取用户上传的图片。
- 创建Canvas对象:利用Canvas绘制图片。
- 调整图片质量:通过调整Canvas的绘制参数,实现图片压缩。
- 导出压缩后的图片:将Canvas内容导出为JPEG格式。
三、Vue3+TS+Canvas实现图片压缩
3.1 项目搭建
首先,我们需要搭建一个Vue3+TypeScript的项目。可以使用Vue CLI进行快速初始化:
vue create my-project
选择Vue3和TypeScript配置。
3.2 编写核心代码
3.2.1 前端组件
<template>
<div>
<input type="file" @change="handleFileChange" />
<button @click="uploadImage">上传图片</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'ImageUploader',
setup() {
const file = ref<File | null>(null);
const handleFileChange = (event: Event) => {
const target = event.target as HTMLInputElement;
if (target.files?.length) {
file.value = target.files[0];
}
};
const uploadImage = async () => {
if (!file.value) {
alert('请选择图片');
return;
}
const compressedFile = await compressImage(file.value);
// 上传压缩后的图片
console.log('上传图片', compressedFile);
};
const compressImage = (file: File): Promise<Blob> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx?.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
} else {
reject(new Error('图片压缩失败'));
}
}, 'image/jpeg', 0.7); // 调整压缩质量
};
img.src = e.target?.result as string;
};
reader.onerror = (e) => {
reject(e);
};
reader.readAsDataURL(file);
});
};
return {
handleFileChange,
uploadImage,
};
},
});
</script>
3.2.2 后端接口
import Koa from 'koa';
import Router from 'koa-router';
import koaBody from 'koa-body';
const app = new Koa();
const router = new Router();
router.post('/upload', koaBody({ multipart: true }), async (ctx) => {
const file = ctx.request.files?.file;
if (file) {
// 处理文件存储逻辑
ctx.body = { message: '图片上传成功' };
} else {
ctx.body = { message: '请上传图片' };
}
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
四、优化与扩展
4.1 图片懒加载
<template>
<img v-img-lazy="imageSrc" />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useIntersectionObserver } from '@vueuse/core';
export default defineComponent({
directives: {
imgLazy: {
mounted(el, binding) {
const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = binding.value;
stop();
}
});
},
},
},
});
</script>
4.2 AI作图与新闻发布
结合AI作图技术,可以实现自动生成新闻封面图的功能。利用SpringBoot和Vue3技术栈,结合AI作画接口(如讯飞认知大模型或百度AI作画接口),可以大幅提升新闻发布的效率。