Files
nodecrypt/web/util.image.js
T

114 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 图片压缩与格式转换工具
export async function processImage(file, callback) {
// 检查webp支持
let webpSupported = await checkWebpSupport();
const img = new Image();
img.onload = function() {
// 限制最大宽高
const maxW = 1280, maxH = 1280;
let w = img.naturalWidth, h = img.naturalHeight;
if (w > maxW || h > maxH) {
const scale = Math.min(maxW / w, maxH / h);
w = Math.round(w * scale);
h = Math.round(h * scale);
}
const canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, w, h);
let dataUrl;
dataUrl = canvas.toDataURL('image/webp', 0.90);
callback(dataUrl);
};
const reader = new FileReader();
reader.onload = function(e) {
img.src = e.target.result;
};
reader.readAsDataURL(file);
}
function checkWebpSupport() {
return new Promise(resolve => {
const img = new window.Image();
img.onload = function() {
resolve(img.width === 1);
};
img.onerror = function() {
resolve(false);
};
img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4TAYAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
});
}
// 国际化提示
const i18n = {
zh: {
tooLarge: '图片过大(超过5MB)',
},
en: {
tooLarge: 'Image is too large (over 5MB)',
}
};
function getLang() {
const lang = navigator.language || navigator.userLanguage;
if (lang && lang.toLowerCase().startsWith('zh')) return 'zh';
return 'en';
}
function t(key) {
const lang = getLang();
return (i18n[lang] && i18n[lang][key]) || i18n['en'][key] || key;
}
/**
* 统一图片发送与粘贴处理
* @param {Object} opts
* @param {string} opts.inputSelector 聊天输入框选择器
* @param {string} opts.attachBtnSelector 附件按钮选择器
* @param {string} opts.fileInputSelector 文件input选择器
* @param {function} opts.onSend 发送图片回调(dataUrl)
*/
export function setupImageSend({ inputSelector, attachBtnSelector, fileInputSelector, onSend }) {
const input = document.querySelector(inputSelector);
const attachBtn = document.querySelector(attachBtnSelector);
const fileInput = document.querySelector(fileInputSelector);
if (fileInput) fileInput.setAttribute('accept', 'image/*');
if (attachBtn && fileInput) {
attachBtn.onclick = () => fileInput.click();
fileInput.onchange = async function() {
if (!fileInput.files || !fileInput.files.length) return;
const file = fileInput.files[0];
if (!file.type.startsWith('image/')) return;
if (file.size > 5 * 1024 * 1024) {
alert(t('tooLarge'));
return;
}
processImage(file, (dataUrl) => {
if (typeof onSend === 'function') onSend(dataUrl);
});
fileInput.value = '';
};
}
// 粘贴图片支持
if (input) {
input.addEventListener('paste', function(e) {
if (!e.clipboardData) return;
for (const item of e.clipboardData.items) {
if (item.type.startsWith('image/')) {
const file = item.getAsFile();
if (!file) continue;
if (file.size > 5 * 1024 * 1024) {
alert(t('tooLarge'));
continue;
}
processImage(file, (dataUrl) => {
if (typeof onSend === 'function') onSend(dataUrl);
});
e.preventDefault();
break;
}
}
});
}
}