🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

Greasy Fork is available in English.

📂 缓存分发状态(共享加速已生效)
🕒 页面同步时间:2026/01/04 10:40:09
🔄 下次更新时间:2026/01/04 11:40:09
手动刷新缓存

Google Image Search - Show Image Dimensions

Displays image dimensions (eg. "1920 × 1080") for each thumbnail on the Google Image Search results page.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name            Google Image Search - Show Image Dimensions
// @name:de         Google Bildersuche - Bildabmessungen anzeigen
// @name:fr         Google Image Search - Afficher les dimensions de l'image
// @name:es         Búsqueda de imágenes de Google - Mostrar las dimensiones de la imagen
// @name:it         Ricerca immagini su Google - Mostra le dimensioni delle immagini
// @name:pl         Wyszukiwanie obrazów Google - Pokaż wymiary obrazu
// @name:ru         Поиск изображений Google - Показать размеры изображений
// @description     Displays image dimensions (eg. "1920 × 1080") for each thumbnail on the Google Image Search results page.
// @description:de  Zeigt die Bildabmessungen (z. B. "1920 × 1080") für jedes Vorschaubild auf der Ergebnisseite der Google-Bildsuche an.
// @description:fr  Affiche les dimensions de l'image (par exemple, "1920 × 1080") pour chaque miniature sur la page de résultats de Google Image Search.
// @description:es  Muestra las dimensiones de la imagen (p. ej., "1920 × 1080") para cada miniatura de la página de resultados de Google Image Search.
// @description:it  Visualizza le dimensioni dell'immagine (ad es. "1920 × 1080") per ogni miniatura nella pagina dei risultati della ricerca immagini di Google.
// @description:pl  Wyświetla wymiary obrazu (np. "1920 × 1080") dla każdej miniaturki na stronie wyników wyszukiwania obrazów Google.
// @description:ru  Отображает размеры изображения (например, "1920 × 1080") для каждой миниатюры на странице результатов поиска изображений Google.
// @namespace       https://github.com/tadwohlrapp
// @author          Tad Wohlrapp
// @version         1.6.0
// @license         MIT
// @homepageURL     https://github.com/tadwohlrapp/google-image-search-show-image-dimensions-userscript
// @supportURL      https://github.com/tadwohlrapp/google-image-search-show-image-dimensions-userscript/issues
// @icon            https://github.com/tadwohlrapp/google-image-search-show-image-dimensions-userscript/raw/main/icon.png
// @grant           unsafeWindow
// @include         https://*.google.tld/*udm=2*
// @include         https://*.google.tld/*lns_surface=*
// @compatible      firefox Tested on Firefox v146 with Violentmonkey v2.31.0, Tampermonkey v5.4.1 and Greasemonkey v4.13.0
// @compatible      chrome Tested on Chrome v143 with Violentmonkey v2.31.0 and Tampermonkey v5.4.1
// @compatible      edge Tested on Edge v143 with Violentmonkey v2.31.0 and Tampermonkey v5.4.0
// @compatible      opera Tested on Opera v125 with Tampermonkey v5.3.6222
// ==/UserScript==

(function () {
  'use strict';

  // Check if url parameter 'udm=2' exists (regular Google Image Search)
  const isImgSearch = () => new URLSearchParams(window.location.search).get('udm') === '2';

  // Check if url parameter 'lns_surface' exists (Google Lens mode)
  const isLens = () => new URLSearchParams(window.location.search).get('lns_surface');

  // Selectors for regular Google Image Search
  const selectors = {
    'wrapper': 'div[data-id="mosaic"][data-viewer-group="1"]>div',
    'item': 'div[data-attrid="images universal"][jsdata]'
  };

  const handleUrlChange = () => {
    if (isLens()) {
      // Different selectors for Google Lens mode ("Search Image with Google Lens" or pasted / uploaded image as Google Search input)
      selectors.wrapper = 'div[data-id="mosaic"][data-viewer-group="1"]>div>div';
      selectors.item = 'div[data-snf][data-snm]';
    };

    // Abort if neither regular Google Image Search (udm=2) nor Google Lens mode
    if (!isImgSearch() && !isLens()) return;

    showDims();
  };

  const showDims = () => {
    const wrapper = document.querySelector(selectors.wrapper);
    if (!wrapper) return;

    // Find all results & exclude the "data-sid-result" attribute we set below (sid = ShowImageDimensions)
    const results = wrapper.querySelectorAll(selectors.item + ':not([data-sid-result])');
    if (!results) return;

    // Loop through all results
    results.forEach((result) => {
      try {
        // Get result ID from jsdata attribute
        const jsdata = result.getAttribute('jsdata') ?? result.querySelector('[jsdata]')?.getAttribute('jsdata');
        const resultId = jsdata?.split(';')[2];
        if (!resultId) return;

        // Access "W_jd" in window object
        const W_jd = unsafeWindow.W_jd;
        const rawResultData = W_jd[resultId];
        const symbols = Object.getOwnPropertySymbols(rawResultData);

        // Traverse down to the data we want
        const level0 = rawResultData[symbols[0]];
        if (!level0) return;
        const level1 = Object.values(level0)[0]?.[1];
        if (!level1) return;
        const level2 = Object.values(level1)[0]?.[3];
        if (!level2) return;

        // Extract full res URL, width and height
        const [imgurl, height, width] = level2;
        if (!width || !height || !imgurl) return;

        // Filter out Meta sites & TikTok which prevent direct full res linking. It's brainrot anyways
        const hn = (new URL(imgurl)).hostname;
        const goodUrl = !hn.startsWith('lookaside') && !hn.startsWith('www.tiktok.com');

        // Create svg icon for full res lightbox
        const icon = createSVG('svg', { viewBox: '0 0 24 24', width: '16', height: '16' }, [
          createSVG('path', { d: 'M19 21H5l-2-2V5l2-2h7v2H5v14h14v-7h2v7l-2 2z' }),
          createSVG('path', { d: 'M21 10h-2V5h-5V3h7z' }),
          createSVG('path', { d: 'M8 14 19 3l2 2-11 11z' })
        ]);

        // Create element for dimensions text
        const dimensionsElement = document.createElement(goodUrl ? 'a' : 'p');
        dimensionsElement.textContent = '';
        if (goodUrl) dimensionsElement.append(icon);
        dimensionsElement.append(`${width} × ${height}`);
        dimensionsElement.classList.add('sid-dims');

        // Create full res link
        if (goodUrl) {
          dimensionsElement.href = imgurl;
          dimensionsElement.onclick = (e) => {
            if (!isKeyPressed) {
              e.preventDefault();
              showLightbox(imgurl);
            };
          };
        };

        // Append everything to the thumbnail
        const thumbnail = isLens() ? result.querySelector('img').closest('[jsdata]').parentElement : result.querySelector('h3');
        thumbnail.style.position = 'relative';
        thumbnail.append(dimensionsElement);

        // Add "data-sid-result" attribute to result
        result.dataset.sidResult = '';
      } catch (error) {
        console.warn('Show Image Dimensions UserScript:', error);
      };
    });
  };

  // Run script on document ready
  handleUrlChange();

  // Run script when title changes
  const titleObserver = new MutationObserver(() => {
    handleUrlChange();
  });

  // Run script with minimal delay when grid changes
  const contentObserver = new MutationObserver(() => {
    setTimeout(() => { showDims() }, 100);
  });

  // Run MutationObservers
  titleObserver.observe(document.querySelector('title'), { subtree: true, characterData: true, childList: true });
  contentObserver.observe(document.querySelector('div#rso'), { childList: true, subtree: true });

  // Create lightbox for full res images
  const lightboxBackdrop = document.createElement('div');
  lightboxBackdrop.classList.add('sid-backdrop');
  const lightboxWrap = document.createElement('div');
  lightboxWrap.classList.add('sid-wrap');
  const lightboxImg = document.createElement('img');
  lightboxWrap.append(lightboxImg);
  lightboxBackdrop.append(lightboxWrap);
  document.body.append(lightboxBackdrop);

  let isKeyPressed = false;
  document.addEventListener('keydown', () => isKeyPressed = true);
  document.addEventListener('keyup', () => isKeyPressed = false);

  // Show full res image
  const showLightbox = imgurl => {
    lightboxBackdrop.classList.add('show');
    lightboxImg.src = imgurl;
    lightboxImg.onload = () => {
      lightboxWrap.classList.add('show');
    };
    lightboxBackdrop.onclick = (e) => {
      hideLightbox(e);
    };
    lightboxImg.onclick = (e) => {
      window.open(imgurl, '_blank');
    };
    document.addEventListener('keydown', closeOnEsc);
  };

  // Hide full res image
  const hideLightbox = () => {
    lightboxBackdrop.classList.remove('show');
    lightboxWrap.classList.remove('show');
    lightboxImg.removeAttribute('src');
    delete lightboxImg.dataset.ilt;
    document.removeEventListener('keydown', closeOnEsc);
  };

  const closeOnEsc = (e) => {
    if (e.key === 'Escape') hideLightbox(e);
  };

  // Helper function to generate small svg icon
  const createSVG = (type, attrs = {}, children = []) => {
    const el = document.createElementNS('http://www.w3.org/2000/svg', type);
    for (const [key, value] of Object.entries(attrs)) {
      el.setAttribute(key, value);
    };
    if (children.length > 0) el.append(...children);
    return el;
  };

  // Add CSS function
  const addStyles = css => {
    const style = document.createElement('style');
    style.textContent = css;
    document.head.appendChild(style);
  };

  // Styles for dimensions and full res lightbox
  addStyles(`
    .sid-dims {
      display: flex;
      gap: 3px;
      position: absolute;
      bottom: 0;
      right: 0;
      margin: 0;
      padding: 4px;
      color: #f1f3f4 !important;
      background-color: rgba(0, 0, 0, 0.6);
      border-radius: 2px 0 12px 0;
      font-family: Roboto-Medium, Roboto, Arial, sans-serif;
      font-size: 10px;
      line-height: 12px;
      text-decoration: none !important;
    }
    .sid-dims svg {
      fill: #f1f3f4;
      height: 12px;
      width: 12px;
      opacity: 0.4;
      pointer-events: none;
    }
    .sid-dims:hover svg {
      opacity: 1;
    }
    .sid-backdrop {
      position: fixed;
      display: flex;
      pointer-events: none;
      opacity: 0;
      transition: all 0.2s ease-in-out;
      top: 0;
      left: 0;
      z-index: 1010;
      justify-content: center;
      align-items: center;
    }
    .sid-backdrop.show {
      pointer-events: all;
      bottom: 0;
      right: 0;
      opacity: 1;
      background-color: rgba(0, 0, 0, 0.6);
    }
    .sid-backdrop.show .sid-wrap {
      z-index: 1011;
      border-radius: 12px;
      cursor: pointer;
      display: block;
      position: relative;
      overflow: hidden;
      transition: all 0.2s ease-in-out;
      background-color: rgba(255, 255, 255, 0.33);
      box-shadow: inset 0px 0px 50px 10px rgba(0, 0, 0, 0.66);
    }
    .sid-backdrop.show .sid-wrap img {
      position: relative;
      display: block;
      z-index: 1012;
      max-width: 95vw;
      max-height: 95vh;
      opacity: 0;
      transition: all 0.2s ease-in-out;
    }
    .sid-backdrop.show .sid-wrap.show {
      background-color: #fff;
      box-shadow: 0px 0px 100px 20px rgba(0, 0, 0, 0.66);
    }
    .sid-backdrop.show .sid-wrap.show img {
      opacity: 1;
    }
  `);
})();