Greasy Fork is available in English.
4-in-1 Welfare: Originals Downloader, AI 2x Sharpen, Google Lens Source, and Auto Color Palette Extractor.
当前为
// ==UserScript==
// @name Pinterest Ultra HD Assistant V6.1 (Pro Designer Tools)
// @namespace http://tampermonkey.net/
// @version 6.1
// @description 4-in-1 Welfare: Originals Downloader, AI 2x Sharpen, Google Lens Source, and Auto Color Palette Extractor.
// @author Pi Xiao
// @match https://*.pinterest.com/*
// @grant GM_openInTab
// @grant GM_setClipboard
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const BRIDGE_PAGE = "https://meishubiji.cn/ai-processing-center/";
// --- 1. 工具函数:获取色号 ---
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
}
// --- 2. 颜色提取引擎 (福利功能) ---
function extractPalette(img, container) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 50; canvas.height = 50; // 缩小采样提高性能
ctx.drawImage(img, 0, 0, 50, 50);
const data = ctx.getImageData(0, 0, 50, 50).data;
let colors = {};
for (let i = 0; i < data.length; i += 20) { // 步进采样
let hex = rgbToHex(data[i], data[i+1], data[i+2]);
colors[hex] = (colors[hex] || 0) + 1;
}
// 取出现次数最多的前 5 个颜色
const sorted = Object.keys(colors).sort((a, b) => colors[b] - colors[a]).slice(0, 5);
const paletteDiv = document.createElement('div');
paletteDiv.className = 'px-palette-bar';
paletteDiv.style = "display: flex; gap: 3px; margin-top: 5px; background: rgba(0,0,0,0.5); padding: 3px; border-radius: 4px;";
sorted.forEach(color => {
const chip = document.createElement('div');
chip.style = `width: 14px; height: 14px; background: ${color}; border-radius: 2px; cursor: copy; border: 1px solid rgba(255,255,255,0.2);`;
chip.title = `Click to copy: ${color}`;
chip.onclick = (e) => {
e.stopPropagation();
GM_setClipboard(color);
const originalText = chip.title;
chip.title = "Copied!";
setTimeout(() => chip.title = originalText, 1000);
};
paletteDiv.appendChild(chip);
});
const oldPalette = container.querySelector('.px-palette-bar');
if (oldPalette) oldPalette.remove();
container.querySelector('.px-helper-bar').appendChild(paletteDiv);
}
// --- 3. 核心算法与显示逻辑 (保持 V6.0) ---
function getOriginalUrl(url) {
return url.replace(/\/(236x|474x|564x|736x|1200x)\//, '/originals/').replace(/\.webp$/, '.jpg');
}
async function processAndShow(imgUrl) {
const originalUrl = getOriginalUrl(imgUrl);
const overlay = document.createElement('div');
overlay.style = "position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.95);z-index:100000;display:flex;flex-direction:column;align-items:center;justify-content:center;color:white;font-family:sans-serif;cursor:zoom-out;";
overlay.innerHTML = '<div style="text-align:center;"><div class="px-spinner"></div><div style="margin-top:15px; font-size:14px; color:#00ffcc;">AI PIXEL RECONSTRUCTION...</div></div><style>.px-spinner { width:30px; height:30px; border:2px solid rgba(0,255,204,0.1); border-top-color:#00ffcc; border-radius:50%; animation:spin .8s linear infinite; margin:0 auto; } @keyframes spin { to { transform:rotate(360deg); } }</style>';
overlay.onclick = () => overlay.remove();
document.body.appendChild(overlay);
const img = new Image();
img.crossOrigin = "Anonymous";
img.src = originalUrl;
img.onload = function() {
overlay.innerHTML = "";
const container = document.createElement('div');
container.style = "text-align:center; width:95%; height:90vh; display:flex; flex-direction:column; cursor:default;";
container.onclick = (e) => e.stopPropagation();
const scrollBox = document.createElement('div');
scrollBox.style = "overflow:auto; border:1px solid #333; border-radius:12px; flex:1; background:#050505;";
const pImg = document.createElement('img');
pImg.src = originalUrl;
pImg.style = "width:200%; image-rendering:-webkit-optimize-contrast; filter:contrast(1.1);";
scrollBox.appendChild(pImg);
const btnAi = document.createElement('button');
btnAi.innerHTML = '🚀 LAUNCH AI 8K ENGINE';
btnAi.style = "background:linear-gradient(45deg, #6a11cb 0%, #2575fc 100%); color:white; border:none; padding:12px 35px; border-radius:50px; font-size:15px; font-weight:bold; cursor:pointer; margin:20px;";
btnAi.onclick = () => window.open(`${BRIDGE_PAGE}?url=${encodeURIComponent(originalUrl)}`, '_blank');
container.appendChild(scrollBox);
container.appendChild(btnAi);
overlay.appendChild(container);
};
img.onerror = () => { window.open(originalUrl, '_blank'); overlay.remove(); };
}
// --- 4. 注入逻辑 ---
function injectButtons() {
const images = document.querySelectorAll('img[src*="pinimg.com"]');
images.forEach(img => {
if (img.width < 100 || img.closest('.px-helper-bar')) return;
const container = img.closest('[data-test-id="pin-visual-wrapper"]') || img.closest('[data-test-id="visual-content-container"]') || img.parentElement;
if (container) {
if (window.getComputedStyle(container).position === 'static') container.style.position = 'relative';
const bar = document.createElement('div');
bar.className = 'px-helper-bar';
bar.style = `position: absolute; top: 10px; left: 10px; z-index: 99; display: flex; flex-direction: column; gap: 4px; opacity: 0; transition: 0.3s; pointer-events: auto;`;
container.addEventListener('mouseenter', () => { bar.style.opacity = "1"; extractPalette(img, container); });
container.addEventListener('mouseleave', () => bar.style.opacity = "0");
const btnStyle = 'color: white; border: none; border-radius: 4px; cursor: pointer; padding: 4px 8px; font-weight: bold; font-size: 9px; box-shadow: 0 2px 5px rgba(0,0,0,0.3); white-space: nowrap;';
const b1 = document.createElement('button'); b1.innerHTML = '🪄 2x HD'; b1.style = btnStyle + 'background: #00BFFF;';
b1.onclick = (e) => { e.preventDefault(); e.stopPropagation(); processAndShow(img.src); };
const b2 = document.createElement('button'); b2.innerHTML = '🖼️ Originals'; b2.style = btnStyle + 'background: #E60023;';
b2.onclick = (e) => { e.preventDefault(); e.stopPropagation(); window.open(getOriginalUrl(img.src), '_blank'); };
const b3 = document.createElement('button'); b3.innerHTML = '🔍 Source'; b3.style = btnStyle + 'background: #34a853;';
b3.onclick = (e) => { e.preventDefault(); e.stopPropagation(); window.open(`https://lens.google.com/uploadbyurl?url=${encodeURIComponent(getOriginalUrl(img.src))}`, '_blank'); };
const btnGroup = document.createElement('div');
btnGroup.style = "display:flex; gap:4px;";
btnGroup.appendChild(b1); btnGroup.appendChild(b2); btnGroup.appendChild(b3);
bar.appendChild(btnGroup);
container.appendChild(bar);
}
});
}
setInterval(injectButtons, 2000);
const observer = new MutationObserver(injectButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();