Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
DJChanahCJD committed Dec 11, 2024
1 parent e56b101 commit 90243da
Showing 1 changed file with 70 additions and 36 deletions.
106 changes: 70 additions & 36 deletions functions/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@ export async function onRequestPost(context) {
// 根据文件类型选择合适的上传方式
let apiEndpoint;
if (uploadFile.type.startsWith('image/')) {
try {
telegramFormData.append("photo", uploadFile);
apiEndpoint = 'sendPhoto';
} catch (error) {
console.error('PHOTO_INVALID_DIMENSIONS. resizing...', error);
const imageBlob = await resizeImage(uploadFile);
telegramFormData.append("photo", imageBlob, fileName);
apiEndpoint = 'sendPhoto';
}
const processedImage = await validateAndResizeImage(uploadFile);
telegramFormData.append("photo", processedImage);
apiEndpoint = 'sendPhoto';

} else if (uploadFile.type.startsWith('audio/')) {
telegramFormData.append("audio", uploadFile);
apiEndpoint = 'sendAudio';
Expand Down Expand Up @@ -118,35 +113,74 @@ function getFileId(response) {
}

// 超过 4096 像素的图片会自动等比压缩
async function resizeImage(file) {
return new Promise((resolve) => {
const img = new Image();
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

img.onload = () => {
const MAX_DIMENSION = 4096;
let width = img.width;
let height = img.height;

// 计算缩放比例
if (width > MAX_DIMENSION || height > MAX_DIMENSION) {
const ratio = Math.min(
MAX_DIMENSION / width,
MAX_DIMENSION / height
);
width = Math.round(width * ratio);
height = Math.round(height * ratio);
}
async function validateAndResizeImage(file) {
return new Promise((resolve, reject) => {
const img = new Image();

// https://www.postman.com/satellite-administrator-38214876/telegram-api/request/b72joh5/sendphoto
img.onload = async () => {
try {
let width = img.width;
let height = img.height;

// 1. 检查是否需要处理
const MAX_RATIO = 20;
const MAX_DIMENSION_SUM = 10000;
const ratio = width / height;
const maxSize = 10 * 1024 * 1024;

// 如果图片完全符合要求,直接返回原文件
if (ratio <= MAX_RATIO &&
ratio >= 1/MAX_RATIO &&
width + height <= MAX_DIMENSION_SUM &&
file.size <= maxSize) {
URL.revokeObjectURL(img.src);
resolve(file);
return;
}

// 2. 需要处理的情况
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);

canvas.toBlob((blob) => {
resolve(blob);
}, file.type, 0.95); // 0.95 是压缩质量
};
// 处理宽高比
if (ratio > MAX_RATIO) {
width = height * MAX_RATIO;
} else if (ratio < 1/MAX_RATIO) {
height = width * MAX_RATIO;
}

// 处理总尺寸
if (width + height > MAX_DIMENSION_SUM) {
const scale = MAX_DIMENSION_SUM / (width + height);
width = Math.floor(width * scale);
height = Math.floor(height * scale);
}

canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);

// 直接压缩为JPEG格式
const finalBlob = await new Promise(resolve =>
canvas.toBlob(resolve, 'image/jpeg', 0.9)
);
if (finalBlob.size > maxSize) { // 如果压缩后图片大小仍然超过10M,则抛出错误
throw new Error(`Image Size Exceeds the ${maxSize} bytes`);
}
URL.revokeObjectURL(img.src);
resolve(finalBlob);
} catch (error) {
URL.revokeObjectURL(img.src);
reject(error);
}
};

img.onerror = () => {
URL.revokeObjectURL(img.src);
reject(new Error('Failed to load image'));
};

img.src = URL.createObjectURL(file);
});
Expand Down

0 comments on commit 90243da

Please sign in to comment.