图片拖拉拽 等比压缩上传
为了在前端对图片文件进行等比压缩后再上传到后端,可以使用 canvas
元素来实现图片的压缩。以下是一个详细的实现步骤:
- 前端实现图片等比压缩:使用
canvas
元素对图片进行压缩。 - 前端上传压缩后的图片:使用
el-upload
组件上传压缩后的图片。 - 后端接收并保存图片:在 Spring Boot 中接收上传的图片并保存。
下面是一个详细的实现示例。
1. 前端实现图片等比压缩
首先,确保你已经安装了 jszip
和 file-saver
库来处理文件压缩。
bash
npm install jszip file-saver
2. 创建拖拽上传组件
修改 DragUpload.vue
组件以支持图片等比压缩和上传。
vue
<template>
<div>
<el-upload
class="upload-dragger"
drag
action="http://localhost:8080/upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:on-change="handleChange"
:auto-upload="false"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</template>
</el-upload>
<el-button style="margin-top: 20px;" type="success" @click="submitUpload">上传到服务器</el-button>
<div v-if="fileList.length > 0">
<h3>已上传文件列表:</h3>
<ul>
<li v-for="(file, index) in fileList" :key="index">
{{ file.name }}
<img v-if="isImage(file)" :src="file.url" alt="Uploaded file" style="max-width: 100px; margin-left: 10px;" />
</li>
</ul>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
export default {
setup() {
const fileList = ref([]);
const handleRemove = (file, fileList) => {
console.log(file, fileList);
};
const handlePreview = (file) => {
console.log(file);
};
const handleChange = (file, fileList) => {
fileList = fileList.slice(-3); // 限制最多上传3个文件
fileList.forEach((file) => {
if (file.raw) {
file.url = URL.createObjectURL(file.raw);
}
});
fileList.value = fileList;
};
const submitUpload = async () => {
const zip = new JSZip();
for (const file of fileList.value) {
if (isImage(file)) {
const compressedFile = await compressImage(file.raw);
zip.file(file.name, compressedFile);
} else {
zip.file(file.name, file.raw);
}
}
const content = await zip.generateAsync({ type: 'blob' });
const formData = new FormData();
formData.append('file', content, 'files.zip');
const response = await fetch('http://localhost:8080/upload', {
method: 'POST',
body: formData
});
if (response.ok) {
console.log('文件上传成功');
} else {
console.error('文件上传失败');
}
};
const isImage = (file) => {
const imageTypes = ['image/jpeg', 'image/png'];
return imageTypes.includes(file.raw.type);
};
const compressImage = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
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;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob((blob) => {
resolve(blob);
}, file.type, 0.8); // 0.8 是压缩质量
};
img.onerror = reject;
img.src = event.target.result;
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
return {
fileList,
handleRemove,
handlePreview,
handleChange,
submitUpload,
isImage
};
}
};
</script>
<style scoped>
.upload-dragger {
width: 600px;
margin: 0 auto;
}
</style>
3. 后端 Spring Boot 接收并解压文件
创建一个 Spring Boot 项目来接收并解压上传的文件。
3.1 添加依赖
在 pom.xml
中添加必要的依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
</dependencies>
3.2 创建文件上传控制器
创建一个控制器来处理文件上传和解压。
java
package com.example.demo.controller;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
@RestController
public class FileUploadController {
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
try {
// 创建临时文件存储上传的压缩文件
File tempFile = File.createTempFile("uploaded", ".zip");
file.transferTo(tempFile);
// 解压文件
ZipFile zipFile = new ZipFile(tempFile);
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
File entryFile = new File("uploads/" + entry.getName());
entryFile.getParentFile().mkdirs();
try (InputStream inputStream = zipFile.getInputStream(entry);
FileOutputStream outputStream = new FileOutputStream(entryFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
}
}
}
// 删除临时文件
tempFile.delete();
return "文件上传并解压成功";
} catch (Exception e) {
e.printStackTrace();
return "文件上传或解压失败";
}
}
}
3.3 配置文件上传大小限制
在 application.properties
中配置文件上传大小限制:
properties
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
3.4 创建上传目录
确保项目中有一个 uploads
目录来存储解压后的文件。你可以在项目根目录下创建这个目录,或者在代码中动态创建。
4. 运行项目
-
启动 Spring Boot 项目:
bash
mvn spring-boot:run
2.启动 Vue 项目:
bash
npm run serve
5. 测试上传功能
- 打开浏览器,访问 Vue 项目(通常是
http://localhost:8080
)。 - 使用拖拽上传组件上传图片文件。
- 点击“上传到服务器”按钮,图片将被等比压缩并上传到 Spring Boot 后端。
- 后端接收文件并解压到
uploads
目录中。
通过以上步骤,你可以在前端实现图片等比压缩并在后端 Spring Boot 架构中接收文件。
文件的拖拉拽上传
在前端实现文件压缩并在后端 Spring Boot 架构中接收文件,可以分为以下几个步骤:
- 前端实现文件压缩:使用 JavaScript 库(如
jszip
)来压缩文件。 - 前端上传压缩后的文件:使用
el-upload
组件上传压缩后的文件。 - 后端接收并解压文件:在 Spring Boot 中接收上传的压缩文件并解压。
下面是一个详细的实现示例。
1. 前端实现文件压缩
首先,安装 jszip
和 file-saver
库来处理文件压缩和保存。
bash
npm install jszip file-saver
2. 创建拖拽上传组件
修改 DragUpload.vue
组件以支持文件压缩和上传。
vue
<template>
<div>
<el-upload
class="upload-dragger"
drag
action="http://localhost:8080/upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
:on-change="handleChange"
:auto-upload="false"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</template>
</el-upload>
<el-button style="margin-top: 20px;" type="success" @click="submitUpload">上传到服务器</el-button>
<div v-if="fileList.length > 0">
<h3>已上传文件列表:</h3>
<ul>
<li v-for="(file, index) in fileList" :key="index">
{{ file.name }}
<img v-if="isImage(file)" :src="file.url" alt="Uploaded file" style="max-width: 100px; margin-left: 10px;" />
</li>
</ul>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
export default {
setup() {
const fileList = ref([]);
const handleRemove = (file, fileList) => {
console.log(file, fileList);
};
const handlePreview = (file) => {
console.log(file);
};
const handleChange = (file, fileList) => {
fileList = fileList.slice(-3); // 限制最多上传3个文件
fileList.forEach((file) => {
if (file.raw) {
file.url = URL.createObjectURL(file.raw);
}
});
fileList.value = fileList;
};
const submitUpload = async () => {
const zip = new JSZip();
fileList.value.forEach((file) => {
zip.file(file.name, file.raw);
});
const content = await zip.generateAsync({ type: 'blob' });
const formData = new FormData();
formData.append('file', content, 'files.zip');
const response = await fetch('http://localhost:8080/upload', {
method: 'POST',
body: formData
});
if (response.ok) {
console.log('文件上传成功');
} else {
console.error('文件上传失败');
}
};
const isImage = (file) => {
const imageTypes = ['image/jpeg', 'image/png'];
return imageTypes.includes(file.raw.type);
};
return {
fileList,
handleRemove,
handlePreview,
handleChange,
submitUpload,
isImage
};
}
};
</script>
<style scoped>
.upload-dragger {
width: 600px;
margin: 0 auto;
}
</style>
3. 后端 Spring Boot 接收并解压文件
创建一个 Spring Boot 项目来接收并解压上传的文件。
3.1 添加依赖
在 pom.xml
中添加必要的依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
</dependencies>
3.2 创建文件上传控制器
创建一个控制器来处理文件上传和解压。
java
package com.example.demo.controller;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
@RestController
public class FileUploadController {
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
try {
// 创建临时文件存储上传的压缩文件
File tempFile = File.createTempFile("uploaded", ".zip");
file.transferTo(tempFile);
// 解压文件
ZipFile zipFile = new ZipFile(tempFile);
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
File entryFile = new File("uploads/" + entry.getName());
entryFile.getParentFile().mkdirs();
try (InputStream inputStream = zipFile.getInputStream(entry);
FileOutputStream outputStream = new FileOutputStream(entryFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
}
}
}
// 删除临时文件
tempFile.delete();
return "文件上传并解压成功";
} catch (Exception e) {
e.printStackTrace();
return "文件上传或解压失败";
}
}
}
3.3 配置文件上传大小限制
在 application.properties
中配置文件上传大小限制:
properties
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
3.4 创建上传目录
确保项目中有一个 uploads
目录来存储解压后的文件。你可以在项目根目录下创建这个目录,或者在代码中动态创建。
4. 运行项目
-
启动 Spring Boot 项目:
bash
mvn spring-boot:run
2.启动 Vue 项目:
bash
npm run serve
5. 测试上传功能
- 打开浏览器,访问 Vue 项目(通常是
http://localhost:8080
)。 - 使用拖拽上传组件上传文件或图片。
- 点击“上传到服务器”按钮,文件将被压缩并上传到 Spring Boot 后端。
- 后端接收文件并解压到
uploads
目录中。
通过以上步骤,你可以在前端实现文件压缩并在后端 Spring Boot 架构中接收文件。