您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
点击图片后,通过浏览器右键菜单上传到 Cloudinary,并复制链接。
// ==UserScript== // @name 上传图片到 Cloudinary(右键菜单版) // @version 1.1 // @description 点击图片后,通过浏览器右键菜单上传到 Cloudinary,并复制链接。 // @author Phinsin666 // @source https://github.com/Phinsin666/Uploading-images-to-Cloudinary // @match *://*/* // @namespace https://gf.qytechs.cn/users/385149 // ==/UserScript== (function () { 'use strict'; const cloudName = 'Cloudinary Cloud Name'; // ← 替换为你的 Cloudinary Cloud Name const uploadPreset = 'tampermonkey_upload'; // ← 替换为你的 Upload Preset let selectedElement = null; // 捕获用户点击的元素 document.addEventListener('click', (e) => { selectedElement = e.target; console.log('[Cloudinary] 选中元素:', selectedElement); }); // 注册(不可用)右键菜单命令 GM_registerMenuCommand('上传选中图片到 Cloudinary', async () => { if (!selectedElement) { alert('请先点击一张图片或含图的元素。'); return; } try { const blob = await getImageBlob(selectedElement); if (!blob) throw new Error('无法识别或提取图片'); await uploadBlobToCloudinary(blob); } catch (err) { alert('❌ 错误:' + err.message); } }); // 判断并提取图片 Blob async function getImageBlob(el) { // 1. <img> if (el.tagName === 'IMG' && el.src) { return fetchToBlob(el.src); } // 2. picture > img if (el.tagName === 'PICTURE') { const img = el.querySelector('img'); if (img?.src) return fetchToBlob(img.src); } // 3. background-image const bg = getComputedStyle(el).backgroundImage; const bgUrlMatch = bg?.match(/url\(["']?(.*?)["']?\)/); if (bgUrlMatch && bgUrlMatch[1]) { return fetchToBlob(bgUrlMatch[1]); } // 4. <canvas> if (el.tagName === 'CANVAS') { const dataUrl = el.toDataURL('image/png'); return dataURLtoBlob(dataUrl); } // 5. <svg> if (el.tagName === 'SVG' || el instanceof SVGElement) { const svgData = new XMLSerializer().serializeToString(el); const svgBlob = new Blob([svgData], { type: 'image/svg+xml' }); // 用 Canvas 转成 PNG const imgUrl = URL.createObjectURL(svgBlob); const pngBlob = await svgToPngBlob(imgUrl); URL.revokeObjectURL(imgUrl); return pngBlob; } return null; } // 上传图片 Blob 到 Cloudinary async function uploadBlobToCloudinary(blob) { const apiUrl = `https://api.cloudinary.com/v1_1/${cloudName}/image/upload`; const formData = new FormData(); formData.append('file', blob); formData.append('upload_preset', uploadPreset); const res = await fetch(apiUrl, { method: 'POST', body: formData }); const data = await res.json(); if (data.secure_url) { GM_setClipboard(data.secure_url); alert(`✅ 上传成功:\n${data.secure_url}`); window.open(data.secure_url, '_blank'); } else { throw new Error(data.error?.message || '上传失败'); } } // URL 转 blob function fetchToBlob(url) { return fetch(url).then(res => res.blob()); } // dataURL 转 blob function dataURLtoBlob(dataurl) { const arr = dataurl.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n); while (n--) u8arr[n] = bstr.charCodeAt(n); return new Blob([u8arr], { type: mime }); } // svg blob url → png blob function svgToPngBlob(svgUrl) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => { const canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); canvas.toBlob(resolve, 'image/png'); }; img.onerror = reject; img.src = svgUrl; }); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址