您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
支持图片裁切和链接粘贴上传到Bangumi
当前为
// ==UserScript== // @name Bangumi 图片上传增强 // @namespace https://bgm.tv/group/topic/431819 // @version 1.2 // @description 支持图片裁切和链接粘贴上传到Bangumi // @author You // @match https://bangumi.tv/character/*/upload_photo // @match https://bangumi.tv/character/*/upload_img // @match https://bangumi.tv/person/*/upload_photo // @match https://bangumi.tv/person/*/upload_img // @match https://bangumi.tv/subject/*/upload_img // @match https://bgm.tv/character/*/upload_photo // @match https://bgm.tv/character/*/upload_img // @match https://bgm.tv/person/*/upload_photo // @match https://bgm.tv/person/*/upload_img // @match https://bgm.tv/subject/*/upload_img // @match https://chii.in/character/*/upload_photo // @match https://chii.in/character/*/upload_img // @match https://chii.in/person/*/upload_photo // @match https://chii.in/person/*/upload_img // @match https://chii.in/subject/*/upload_img // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/cropper.min.js // @resource cropperCSS https://cdn.jsdelivr.net/npm/[email protected]/dist/cropper.min.css // @license MIT // ==/UserScript== (function() { 'use strict'; // 添加Cropper.js CSS const cropperCSS = GM_getResourceText('cropperCSS'); const style = document.createElement('style'); style.textContent = cropperCSS; document.head.appendChild(style); const fileInput = document.querySelector('input[type="file"][name="picfile"]'); if (!fileInput) return; // 创建UI容器 const container = document.createElement('div'); container.style.marginTop = '15px'; // 预览容器 const previewContainer = document.createElement('div'); previewContainer.style.marginBottom = '10px'; previewContainer.style.maxWidth = '300px'; previewContainer.style.display = 'none'; const previewImage = document.createElement('img'); previewImage.id = 'preview-image'; previewImage.style.maxWidth = '100%'; previewImage.style.maxHeight = '200px'; previewImage.style.border = '1px solid #ddd'; const previewText = document.createElement('div'); previewText.style.marginTop = '5px'; previewText.style.fontSize = '0.8em'; previewText.style.color = '#666'; // 控制按钮 const controls = document.createElement('div'); controls.style.marginTop = '10px'; controls.style.display = 'none'; const cropBtn = document.createElement('button'); cropBtn.textContent = '裁切图片'; cropBtn.style.marginRight = '5px'; const confirmBtn = document.createElement('button'); confirmBtn.textContent = '确认裁切'; confirmBtn.style.marginRight = '5px'; confirmBtn.style.display = 'none'; const cancelBtn = document.createElement('button'); cancelBtn.textContent = '取消裁切'; cancelBtn.style.display = 'none'; // 组装UI previewContainer.appendChild(previewImage); previewContainer.appendChild(previewText); controls.appendChild(cropBtn); controls.appendChild(confirmBtn); controls.appendChild(cancelBtn); container.appendChild(previewContainer); container.appendChild(controls); fileInput.parentNode.insertBefore(container, fileInput.nextSibling); // 支持的图片后缀 const imageExtensions = ['jpg', 'png', 'gif']; let currentFile = null; let cropper = null; let isCropping = false; // 检查是否是图片URL function isImageUrl(text) { try { const url = new URL(text); const ext = url.pathname.split('.').pop().toLowerCase(); return imageExtensions.includes(ext); } catch { return false; } } // 从URL获取图片文件 function fetchImageFromUrl(url) { previewText.textContent = '正在下载图片...'; previewContainer.style.display = 'block'; return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: url, responseType: 'blob', onload: function(response) { const blob = response.response; const fileName = url.split('/').pop(); const file = new File([blob], fileName, { type: blob.type }); resolve(file); }, onerror: function(error) { reject(new Error('图片下载失败: ' + error.statusText)); } }); }); } // 初始化裁切工具 function initCropper() { if (cropper) { cropper.destroy(); } cropper = new Cropper(previewImage, { viewMode: 1, autoCropArea: 0.8, responsive: true, movable: true, rotatable: true, scalable: true, zoomable: true }); } // 开始裁切 function startCropping(e) { e.preventDefault(); // 阻止默认行为,防止页面刷新 if (!currentFile) return; isCropping = true; initCropper(); cropBtn.style.display = 'none'; confirmBtn.style.display = 'inline-block'; cancelBtn.style.display = 'inline-block'; previewText.textContent = '拖动边框调整裁切区域,然后点击"确认裁切"'; } // 确认裁切 function confirmCrop(e) { e.preventDefault(); if (!cropper || !isCropping) return; cropper.getCroppedCanvas({ fillColor: 'transparent' }).toBlob(blob => { const fileName = currentFile.name.replace(/\.[^/.]+$/, '') + '_cropped.png'; currentFile = new File([blob], fileName, { type: 'image/png' }); // 更新文件输入 const dataTransfer = new DataTransfer(); dataTransfer.items.add(currentFile); fileInput.files = dataTransfer.files; // 更新预览 updatePreview(currentFile); endCropping(); }, 'image/png'); } // 取消裁切 function cancelCrop(e) { e.preventDefault(); if (!isCropping) return; updatePreview(currentFile); endCropping(); } // 结束裁切模式 function endCropping() { isCropping = false; if (cropper) { cropper.destroy(); cropper = null; } cropBtn.style.display = 'inline-block'; confirmBtn.style.display = 'none'; cancelBtn.style.display = 'none'; } // 更新预览 function updatePreview(file) { if (!file) { previewContainer.style.display = 'none'; controls.style.display = 'none'; return false; } const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']; if (!allowedTypes.includes(file.type)) { previewText.textContent = `错误:不支持的文件格式 (${file.type}),请上传 JPG/PNG/GIF 图片`; previewImage.style.display = 'none'; previewContainer.style.display = 'block'; controls.style.display = 'none'; return false; } const reader = new FileReader(); reader.onload = function(e) { previewImage.src = e.target.result; previewImage.style.display = 'block'; previewText.textContent = `已选择: ${file.name} (${Math.round(file.size/1024)}KB)`; previewContainer.style.display = 'block'; controls.style.display = 'block'; // 重置裁切状态 endCropping(); }; reader.readAsDataURL(file); currentFile = file; return true; } // 事件监听 cropBtn.addEventListener('click', startCropping); confirmBtn.addEventListener('click', confirmCrop); cancelBtn.addEventListener('click', cancelCrop); // 监听文件输入变化 fileInput.addEventListener('change', function() { if (this.files.length > 0) { updatePreview(this.files[0]); } }); // 监听粘贴事件 document.addEventListener('paste', async function(e) { // 检查剪贴板中的图片 if (e.clipboardData.items && e.clipboardData.items.length > 0) { for (let i = 0; i < e.clipboardData.items.length; i++) { const item = e.clipboardData.items[i]; if (item.type.indexOf('image') !== -1) { const blob = item.getAsFile(); if (updatePreview(blob)) { const dataTransfer = new DataTransfer(); dataTransfer.items.add(blob); fileInput.files = dataTransfer.files; } e.preventDefault(); return; } } } // 检查剪贴板中的文本(图片URL) const pastedText = e.clipboardData.getData('text/plain').trim(); if (isImageUrl(pastedText)) { e.preventDefault(); try { const imageFile = await fetchImageFromUrl(pastedText); if (updatePreview(imageFile)) { const dataTransfer = new DataTransfer(); dataTransfer.items.add(imageFile); fileInput.files = dataTransfer.files; } } catch (error) { previewText.textContent = error.message; previewImage.style.display = 'none'; previewContainer.style.display = 'block'; } } }); // 添加提示信息 const hint = document.createElement('div'); hint.innerHTML = '<div style="color:#666;font-size:0.9em;margin-bottom:10px;">提示:可直接粘贴图片或图片链接</div>'; fileInput.parentNode.insertBefore(hint, fileInput.nextSibling); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址