闽公网安备 35020302035485号
前言
在现代网络应用中,图像处理是一项重要的任务,尤其是在需要展示用户上传的图片时。但是,经常会面临两个主要问题:图像大小和图像安全。一方面,大尺寸的图片会增加加载时间,降低用户体验,另一方面,保护图片免受盗用或篡改是至关重要的。在本文中,我们将讨论如何通过前端技术来解决这些问题,具体而言,我们将关注图像的压缩和水印添加。
/**
* 堆代码 duidaima.com
* 将图像文件压缩以减小其大小。
* @param {File} file - 要压缩的图像文件。
* @param {number} maxSizeMB - 压缩后图像的最大大小,以兆字节为单位。
* @returns {Promise<File>} 一个解析为压缩后图像文件的 Promise。
*/
compressImage(file, maxSizeMB) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = function () {
let img = new Image();
img.onload = function () {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
let maxSizeBytes = maxSizeMB * 1024 * 1024;
let scaleFactor = 0.5;
if (file.size > maxSizeBytes) {
scaleFactor = Math.min(
scaleFactor,
Math.sqrt(maxSizeBytes / file.size)
); // 计算缩放比例,保持宽高比
}
canvas.width = img.width * scaleFactor;
canvas.height = img.height * scaleFactor;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob(
(blob) => {
const compressedFile = new File([blob], file.name, {
type: file.type,
lastModified: Date.now(),
});
resolve(compressedFile);
},
file.type,
0.8 // 设置压缩质量参数为 0.8
);
};
img.onerror = reject;
img.src = reader.result;
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
},
这段代码实现了一个compressImage函数,它接受一个图像文件和最大允许大小作为参数,并返回一个Promise对象,解析为压缩后的图像文件。主要步骤包括:/**
* 添加水印到图片
* @param {File} file 图片文件
* @param {string} gasName 油站名称
* @param {string} location 地址
* @returns {Promise<Blob>} 返回添加水印后的 Blob 对象
*/
addWatermarkToImage(file, gasName, location) {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const watermarkWidthPercentage = 0.9;
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
ctx.fillStyle = "rgba(0, 0, 0, 0.2)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
const watermarkWidth = canvas.width * watermarkWidthPercentage;
const watermarkX = (canvas.width - watermarkWidth) / 2;
const currentDate = new Date();
const timeString = currentDate.toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
});
const dateString = currentDate.toLocaleDateString();
const dayOfWeek = new Intl.DateTimeFormat("en-US", {
weekday: "long",
}).format(currentDate);
CanvasUtils.drawText(
ctx,
`${dateString} ${dayOfWeek} ${timeString}`,
CanvasUtils.calculateFontSize(watermarkWidth),
CanvasUtils.calculateFontSize(watermarkWidth) * 2,
watermarkX + watermarkWidth / 2
);
CanvasUtils.drawText(
ctx,
gasName,
CanvasUtils.calculateFontSize(watermarkWidth),
CanvasUtils.calculateFontSize(watermarkWidth) * 3.5,
watermarkX + watermarkWidth / 2
);
CanvasUtils.drawText(
ctx,
location,
CanvasUtils.calculateFontSize(watermarkWidth),
CanvasUtils.calculateFontSize(watermarkWidth) * 5,
watermarkX + watermarkWidth / 2
);
canvas.toBlob((blob) => {
resolve(blob);
}, file.type);
};
img.onerror = (error) => {
reject(error);
};
});
},
这段代码实现了一个addWatermarkToImage函数,它接受一个图片文件和水印信息作为参数,并返回一个Promise对象,解析为添加水印后的Blob对象。主要步骤包括: