// ==UserScript==
// @name 上传图片到 Cloudinary(右键菜单版)
// @version 1.1
// @description 点击图片后,通过浏览器右键菜单上传到 Cloudinary,并复制链接。
// @author Phinsin666
// @source https://github.com/Phinsin666/Uploading-images-to-Cloudinary
// @match *://*/*
// @namespace https://greasyfork.org/users/385149
// @downloadURL https://update.greasyfork.icu/scripts/534677/%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E5%88%B0%20Cloudinary%EF%BC%88%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E7%89%88%EF%BC%89.user.js
// @updateURL https://update.greasyfork.icu/scripts/534677/%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E5%88%B0%20Cloudinary%EF%BC%88%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E7%89%88%EF%BC%89.meta.js
// ==/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.
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.