Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore

This file was deleted.

83 changes: 74 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,86 @@
# Image Extract
# Image Extract for Chrome

Pulls images out of the current tab to show you all the images on a page when you click the icon. This is a firefox web extension: https://addons.mozilla.org/en-US/firefox/addon/image-extract/
A minimal Chrome extension that extracts all images from the current tab and displays them in a new tab. Chrome/Edge port of [Skeletonxf's Firefox extension](https://github.com/Skeletonxf/image-extract).

## Features

Before:
- Click the extension icon or press `Alt+Shift+I` to extract images
- Finds images from `<img>` tags, CSS backgrounds, `<picture>` elements, video posters, and SVG images
- Displays all found images in a clean dark-themed grid view
- Shows **resolution**, **format**, and **file size** for each image
- Filter images by URL
- Sort by filename
- Click any image to open it in a new window
- Download images directly

![Before running](../master/screenshots/before.png?raw=true)
## Installation

After:
### Method 1: Load unpacked (Developer Mode)

![After running](../master/screenshots/after.png?raw=true)
1. Unzip `image-extract-chrome.zip`
2. Open Chrome and go to `chrome://extensions/`
3. Enable **"Developer mode"** (toggle in top right)
4. Click **"Load unpacked"**
5. Select the `image-extract-chrome` folder
6. Done! Click the extension icon on any page to extract images.

Mobile:
### Method 2: Edge Browser

![After running](../master/screenshots/mobile-after.png?raw=true)
Works the same way in Microsoft Edge:
1. Go to `edge://extensions/`
2. Enable "Developer mode"
3. Click "Load unpacked"
4. Select the folder

## Usage

1. Navigate to any webpage with images
2. Click the Image Extract icon in the toolbar (or press `Alt+Shift+I`)
3. A new tab opens showing all extracted images with metadata
4. Use the filter box to search for specific images
5. Click any image to open it full size, or click Download to save it

## Fork & Contribute

This is an unofficial Chrome port. To contribute or create your own version:

1. **Fork the original repo**: Go to https://github.com/Skeletonxf/image-extract and click "Fork"
2. **Create a Chrome branch**:
```bash
git checkout -b chrome-port
```
3. **Replace the files** with the ones from this zip
4. **Push and create a PR** (or maintain your own fork)

Alternatively, create a new repo for the Chrome version:
1. Create a new GitHub repository
2. Extract this zip and push the contents
3. Link back to the original project in your README

## Changelog

### v1.1.0
- Added resolution, format, and file size display for each image
- Fixed buttons (CSP compliance)
- Open now opens in new window while keeping viewer open
- Download actually downloads the file (falls back to open if CORS blocks)

### v1.0.0
- Initial Chrome port
- Manifest V3 with service worker
- Dark theme viewer with filter/sort

## Differences from Firefox version

- Uses Manifest V3 (Chrome's modern extension format)
- Service worker instead of background page
- Different UI with dark theme and metadata display
- Added filtering and sorting features

## License

This project is licensed under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version or version 2.
GPL-3.0 (same as original)

## Credits

Original Firefox extension by [Skeletonxf](https://github.com/Skeletonxf/image-extract)
7 changes: 0 additions & 7 deletions background-page.html

This file was deleted.

139 changes: 139 additions & 0 deletions background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Background service worker for Image Extract (Chrome MV3)

chrome.action.onClicked.addListener(async (tab) => {
if (!tab.id) return;

// Don't run on chrome:// or edge:// pages
if (tab.url?.startsWith('chrome://') || tab.url?.startsWith('edge://') || tab.url?.startsWith('about:')) {
console.log('Cannot run on browser internal pages');
return;
}

try {
// Inject the content script to extract images
const results = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: extractImages
});

if (results && results[0] && results[0].result) {
const imageData = results[0].result;

// Create a new tab with the extracted images
const viewerTab = await chrome.tabs.create({
url: chrome.runtime.getURL('viewer.html')
});

// Wait for the tab to load, then send the image data
chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
if (tabId === viewerTab.id && changeInfo.status === 'complete') {
chrome.tabs.onUpdated.removeListener(listener);
chrome.tabs.sendMessage(viewerTab.id, {
type: 'IMAGES_DATA',
images: imageData.images,
sourceUrl: imageData.sourceUrl,
sourceTitle: imageData.sourceTitle
});
}
});
}
} catch (error) {
console.error('Error extracting images:', error);
}
});

// This function runs in the context of the web page
function extractImages() {
const images = new Set();

// Get all <img> elements
document.querySelectorAll('img').forEach(img => {
// Get the actual displayed source (handles srcset, lazy loading, etc.)
const src = img.currentSrc || img.src;
if (src && !src.startsWith('data:') && src.length > 0) {
images.add(src);
}

// Also check srcset for higher resolution versions
if (img.srcset) {
img.srcset.split(',').forEach(srcsetEntry => {
const url = srcsetEntry.trim().split(/\s+/)[0];
if (url && !url.startsWith('data:')) {
images.add(url);
}
});
}
});

// Get background images from all elements
document.querySelectorAll('*').forEach(el => {
const style = window.getComputedStyle(el);
const bgImage = style.backgroundImage;

if (bgImage && bgImage !== 'none') {
// Extract URLs from background-image (handles multiple backgrounds)
const urlMatches = bgImage.matchAll(/url\(["']?([^"')]+)["']?\)/g);
for (const match of urlMatches) {
const url = match[1];
if (url && !url.startsWith('data:')) {
// Resolve relative URLs
try {
const absoluteUrl = new URL(url, window.location.href).href;
images.add(absoluteUrl);
} catch (e) {
// Invalid URL, skip
}
}
}
}
});

// Get images from <picture> elements
document.querySelectorAll('picture source').forEach(source => {
if (source.srcset) {
source.srcset.split(',').forEach(srcsetEntry => {
const url = srcsetEntry.trim().split(/\s+/)[0];
if (url && !url.startsWith('data:')) {
try {
const absoluteUrl = new URL(url, window.location.href).href;
images.add(absoluteUrl);
} catch (e) {
// Invalid URL, skip
}
}
});
}
});

// Get images from <video> poster attributes
document.querySelectorAll('video[poster]').forEach(video => {
const poster = video.poster;
if (poster && !poster.startsWith('data:')) {
try {
const absoluteUrl = new URL(poster, window.location.href).href;
images.add(absoluteUrl);
} catch (e) {
// Invalid URL, skip
}
}
});

// Get SVG images
document.querySelectorAll('svg image').forEach(svgImage => {
const href = svgImage.getAttribute('href') || svgImage.getAttribute('xlink:href');
if (href && !href.startsWith('data:')) {
try {
const absoluteUrl = new URL(href, window.location.href).href;
images.add(absoluteUrl);
} catch (e) {
// Invalid URL, skip
}
}
});

return {
images: Array.from(images),
sourceUrl: window.location.href,
sourceTitle: document.title
};
}
Binary file added icons/icon-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon-48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions icons/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 30 additions & 40 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,50 +1,40 @@
{
"description": "Pulls images out of the current tab",
"manifest_version": 3,
"homepage_url": "https://github.com/Skeletonxf/image-extract",
"name": "Image extract",
"version": "2.3",

"permissions": ["menus", "activeTab", "storage", "scripting"],

"background": {
"page": "/background-page.html"
},

"browser_specific_settings": {
"gecko": {
"id": "{6381b0dc-8bef-47d0-8c31-6fffbdd8ec7f}",
"strict_min_version": "129.0"
}
},

"name": "Image Extract",
"version": "1.1.0",
"description": "Extracts all images from the current tab and shows them in a new tab",
"permissions": [
"activeTab",
"scripting"
],
"action": {
"default_icon": "icons/arrow.svg",
"default_title": "Image extract"
"default_icon": {
"16": "icons/icon-16.png",
"32": "icons/icon-32.png",
"48": "icons/icon-48.png",
"128": "icons/icon-128.png"
},
"default_title": "Extract Images"
},
"icons": {
"16": "icons/icon-16.png",
"32": "icons/icon-32.png",
"48": "icons/icon-48.png",
"128": "icons/icon-128.png"
},

"options_ui": {
"page": "/settings/settings.html"
"background": {
"service_worker": "background.js"
},

"commands": {
"extract-shortcut-1": {
"suggested_key": {
"default": "Ctrl+E"
},
"description": "Run image extract on current tab from keyboard shortcut (1)"
},
"extract-shortcut-2": {
"suggested_key": {
"default": "Alt+Shift+E"
},
"description": "Run image extract on current tab from keyboard shortcut (2)"
},
"extract-shortcut-3": {
"_execute_action": {
"suggested_key": {
"default": "Alt+Shift+I"
},
"description": "Run image extract on current tab from keyboard shortcut (3)"
},
"description": "Extract images from current tab"
}
}
},
"web_accessible_resources": [{
"resources": ["viewer.html", "viewer.js"],
"matches": ["<all_urls>"]
}]
}
2 changes: 0 additions & 2 deletions push.sh

This file was deleted.

3 changes: 0 additions & 3 deletions release.sh

This file was deleted.

9 changes: 0 additions & 9 deletions settings/defaults.js

This file was deleted.

Binary file removed settings/manage-extension-shortcuts.png
Binary file not shown.
Loading