浏览器插件-图片信息识别工具

有客户提了这么个需求,鼠标放到图片上出现一个显示框,可以显示图片大小格式,分辨率

研究再三(其实这个是库存的)做了出来

决定其名为:绝命图库图片识别V1.0 对就是他

content.js

let isEnabled = false;
let infoTooltip = null;

// 初始化
function init() {
  // 创建信息提示框
  infoTooltip = document.createElement('div');
  infoTooltip.className = 'image-info-tooltip';
  infoTooltip.style.display = 'none';
  document.body.appendChild(infoTooltip);
  
  // 从存储中获取当前状态
  chrome.storage.sync.get('enabled', function(data) {
    isEnabled = data.enabled || false;
    if (isEnabled) {
      addImageListeners();
    }
  });
  
  // 监听来自popup的消息
  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.action === 'toggleStatus') {
      isEnabled = request.enabled;
      
      if (isEnabled) {
        addImageListeners();
      } else {
        removeImageListeners();
        hideTooltip();
      }
    }
  });
}

// 添加图片监听器
function addImageListeners() {
  const images = document.querySelectorAll('img');
  images.forEach(img => {
    img.addEventListener('mouseover', showImageInfo);
    img.addEventListener('mouseout', hideTooltip);
    img.addEventListener('mousemove', moveTooltip);
  });
  
  // 监听DOM变化,处理动态加载的图片
  if (!window.imageObserver) {
    window.imageObserver = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        if (mutation.addedNodes.length) {
          mutation.addedNodes.forEach(node => {
            if (node.nodeName === 'IMG') {
              node.addEventListener('mouseover', showImageInfo);
              node.addEventListener('mouseout', hideTooltip);
              node.addEventListener('mousemove', moveTooltip);
            } else if (node.querySelectorAll) {
              const images = node.querySelectorAll('img');
              images.forEach(img => {
                img.addEventListener('mouseover', showImageInfo);
                img.addEventListener('mouseout', hideTooltip);
                img.addEventListener('mousemove', moveTooltip);
              });
            }
          });
        }
      });
    });
    
    window.imageObserver.observe(document.body, {
      childList: true,
      subtree: true
    });
  }
}

// 移除图片监听器
function removeImageListeners() {
  const images = document.querySelectorAll('img');
  images.forEach(img => {
    img.removeEventListener('mouseover', showImageInfo);
    img.removeEventListener('mouseout', hideTooltip);
    img.removeEventListener('mousemove', moveTooltip);
  });
  
  if (window.imageObserver) {
    window.imageObserver.disconnect();
    window.imageObserver = null;
  }
}

// 显示图片信息
function showImageInfo(event) {
  if (!isEnabled) return;
  
  const img = event.target;
  const imgSrc = img.src;
  
  // 获取图片格式
  const format = getImageFormat(imgSrc);
  
  // 获取图片尺寸
  const width = img.naturalWidth || img.width;
  const height = img.naturalHeight || img.height;
  
  // 计算图片文件大小(如果已加载)
  let sizeInfo = '加载中...';
  
  if (img.complete) {
    fetchImageSize(imgSrc).then(size => {
      if (infoTooltip) {
        infoTooltip.innerHTML = `
          <div>格式: ${format}</div>
          <div>尺寸: ${width} x ${height}px</div>
          <div>大小: ${formatFileSize(size)}</div>
        `;
      }
    }).catch(err => {
      console.error('获取图片大小失败:', err);
      if (infoTooltip) {
        infoTooltip.innerHTML = `
          <div>格式: ${format}</div>
          <div>尺寸: ${width} x ${height}px</div>
          <div>大小: 无法获取</div>
        `;
      }
    });
  }
  
  // 初始显示
  infoTooltip.innerHTML = `
    <div>格式: ${format}</div>
    <div>尺寸: ${width} x ${height}px</div>
    <div>大小: ${sizeInfo}</div>
  `;
  
  infoTooltip.style.display = 'block';
  moveTooltip(event);
}

// 移动提示框
function moveTooltip(event) {
  if (!isEnabled || !infoTooltip) return;
  
  const x = event.pageX + 15;
  const y = event.pageY + 15;
  
  infoTooltip.style.left = `${x}px`;
  infoTooltip.style.top = `${y}px`;
}

// 隐藏提示框
function hideTooltip() {
  if (infoTooltip) {
    infoTooltip.style.display = 'none';
  }
}

// 获取图片格式
function getImageFormat(url) {
  // 从URL中提取扩展名
  const extension = url.split('.').pop().toLowerCase().split(/[?#]/)[0];
  
  // 常见图片格式映射
  const formatMap = {
    'jpg': 'JPEG',
    'jpeg': 'JPEG',
    'png': 'PNG',
    'gif': 'GIF',
    'webp': 'WebP',
    'svg': 'SVG',
    'bmp': 'BMP',
    'ico': 'ICO'
  };
  
  return formatMap[extension] || extension.toUpperCase() || '未知';
}

// 获取图片文件大小
async function fetchImageSize(url) {
  try {
    const response = await fetch(url, { method: 'HEAD' });
    const size = response.headers.get('content-length');
    return size ? parseInt(size) : null;
  } catch (error) {
    console.error('获取图片大小出错:', error);
    return null;
  }
}

// 格式化文件大小
function formatFileSize(bytes) {
  if (!bytes) return '未知';
  
  const units = ['B', 'KB', 'MB', 'GB'];
  let size = bytes;
  let unitIndex = 0;
  
  while (size >= 1024 && unitIndex < units.length - 1) {
    size /= 1024;
    unitIndex++;
  }
  
  return `${size.toFixed(2)} ${units[unitIndex]}`;
}

// 初始化插件
init();

manifest.json

{
  "manifest_version": 3,
  "name": "绝命图库图片识别V1.0",
  "version": "1.0",
  "description": "悬停在图片上时自动识别并显示图片格式和大小",
  "permissions": ["activeTab", "storage"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "images/icon16.png",
      "48": "images/icon48.png",
      "128": "images/icon128.png"
    }
  },
  "icons": {
    "16": "images/icon16.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "css": ["styles.css"]
    }
  ]
}

popup.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>绝命图库图片识别V1.0</title>
  <style>
    body {
      width: 200px;
      padding: 10px;
      font-family: Arial, sans-serif;
    }
    .toggle-container {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 10px;
    }
    .switch {
      position: relative;
      display: inline-block;
      width: 50px;
      height: 24px;
    }
    .switch input {
      opacity: 0;
      width: 0;
      height: 0;
    }
    .slider {
      position: absolute;
      cursor: pointer;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: #ccc;
      transition: .4s;
      border-radius: 24px;
    }
    .slider:before {
      position: absolute;
      content: "";
      height: 16px;
      width: 16px;
      left: 4px;
      bottom: 4px;
      background-color: white;
      transition: .4s;
      border-radius: 50%;
    }
    input:checked + .slider {
      background-color: #2196F3;
    }
    input:checked + .slider:before {
      transform: translateX(26px);
    }
    .status {
      font-size: 14px;
      margin-top: 5px;
      text-align: center;
    }
  </style>
</head>
<body>
  <h2>图片信息识别工具</h2>
  <div class="toggle-container">
    <span>启用功能:</span>
    <label class="switch">
      <input type="checkbox" id="toggleSwitch">
      <span class="slider"></span>
    </label>
  </div>
  <div class="status" id="statusText">当前状态:已关闭</div>
  <script src="popup.js"></script>
</body>
</html>

popup.js

document.addEventListener('DOMContentLoaded', function() {
  const toggleSwitch = document.getElementById('toggleSwitch');
  const statusText = document.getElementById('statusText');
  
  // 从存储中获取当前状态
  chrome.storage.sync.get('enabled', function(data) {
    toggleSwitch.checked = data.enabled || false;
    updateStatusText();
  });
  
  // 监听开关变化
  toggleSwitch.addEventListener('change', function() {
    const isEnabled = toggleSwitch.checked;
    
    // 保存状态到存储
    chrome.storage.sync.set({enabled: isEnabled}, function() {
      updateStatusText();
      
      // 向当前标签页发送消息
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        if (tabs[0]) {
          chrome.tabs.sendMessage(tabs[0].id, {action: 'toggleStatus', enabled: isEnabled});
        }
      });
    });
  });
  
  function updateStatusText() {
    statusText.textContent = '当前状态:' + (toggleSwitch.checked ? '已开启' : '已关闭');
  }
});

styles.css

.image-info-tooltip {
  position: absolute;
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 14px;
  z-index: 10000;
  pointer-events: none;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
  max-width: 300px;
  line-height: 1.5;
}

.image-info-tooltip div {
  margin: 2px 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值