有客户提了这么个需求,鼠标放到图片上出现一个显示框,可以显示图片大小格式,分辨率
研究再三(其实这个是库存的)做了出来
决定其名为:绝命图库图片识别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;
}