PNG sprite extraction is NOT supported in Google Apps Script due to technical limitations. However, most mapeosettings files will work fine because they include individual PNG files that ARE supported.
What it looks like:
mapeosettings/
├── icons/
│ ├── animal-small@1x.png
│ ├── animal-medium@1x.png
│ ├── animal-large@1x.png
│ ├── building-small@1x.png
│ ├── building-medium@1x.png
│ └── ... (18 total files)
Status: Fully supported and working
Implementation: src/importCategory/extractPngIcons.ts
Priority Order:
- medium@1x.png (preferred)
- small@1x.png (fallback)
- large@1x.png (fallback)
- Then tries @2x and @3x resolutions
Test File: src/test/mapeo-default-min.mapeosettings (18 PNG files)
What it looks like:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<symbol id="building-12px">
<rect width="20" height="20" x="2" y="2" fill="#B209B2" />
</symbol>
<symbol id="river-12px">
<path d="M2,12 C5,8 8,16..." stroke="#0D8DEF" />
</symbol>
</svg>
Status: Fully supported with recent fixes
Implementation: src/importCategory/parseIconSprite.ts
Fixes Applied:
- ✅ Proper XML namespace handling
- ✅ Universal element support (rect, circle, path, polygon, etc.)
- ✅ Nested element handling
- ✅ Attribute preservation
Recent Improvements: See ICON_PARSING_FIX.md
What it looks like:
mapeosettings/
├── icons.png (200x100 PNG with 2 icons)
└── icons.json (metadata with coordinates)
icons.json example:
{
"animal-100px": {
"width": 100,
"height": 100,
"x": 0,
"y": 0,
"pixelRatio": 1
},
"building-100px": {
"width": 100,
"height": 100,
"x": 100,
"y": 0,
"pixelRatio": 1
}
}
Status: NOT SUPPORTED
Why not supported:
Google Apps Script lacks essential image processing capabilities:
-
No Image Processing Libraries
- No Canvas API
- No ImageMagick, Sharp, Jimp, etc.
- No pixel manipulation capabilities
-
No Binary Data Access
- Cannot decode PNG format
- Cannot read pixel data
- Cannot extract sub-regions
-
No Native Image APIs
DriveApphandles files as opaque blobs- No cropping/transformation functions
- No image composition capabilities
What Would Be Needed:
// PSEUDOCODE - NOT POSSIBLE IN APPS SCRIPT
const iconMetadata = JSON.parse(iconsJson);
const spriteImage = loadPNG(iconsPng);
for (const [iconName, coords] of Object.entries(iconMetadata)) {
// Cannot do this in Apps Script:
const croppedImage = cropImage(
spriteImage,
coords.x,
coords.y,
coords.width,
coords.height
);
saveToDrive(croppedImage, `${iconName}.png`);
}
All of the above operations are impossible in Apps Script.
Most mapeosettings files contain multiple icon formats:
mapeosettings-file/
├── icons.png ← PNG sprite (CAN'T PARSE)
├── icons.json ← Metadata (detected but unusable)
├── icons.svg ← SVG sprite (CAN PARSE ✓)
├── icons/ ← Individual PNGs (CAN PARSE ✓)
│ ├── animal-small@1x.png
│ ├── animal-medium@1x.png
│ ├── animal-large@1x.png
│ └── ...
├── metadata.json
├── presets.json
├── translations.json
└── VERSION
Result: Even though PNG sprite can't be parsed, the individual PNGs or SVG sprite work fine.
UPDATED Oct 9, 2025: Priority changed to SVG-first
The import process tries multiple sources in this order:
1. SVG sprite (icons.svg) ← PRIMARY (changed)
↓ If none found
2. Individual PNG files (icons/ directory) ← FALLBACK
↓ If none found
3. PNG sprite (icons.png) → ⚠️ Shows warning, cannot extract
Code Location: src/importCategory/parseFiles.ts:304-433
Why Changed:
- ✅ Matches
mapeo-config-deconstructorbehavior - ✅ SVG files are scalable and higher quality
- ✅ Resolves "broken PNG" issues
See: SVG_PRIORITY_CHANGE.md for detailed information about this change.
=== ICON EXTRACTION PHASE 1: PNG Icons ===
Icons before PNG extraction: 0
Found icons/ directory, extracting PNG icons
✓ Extracted 18 PNG icons
✓ Added PNG icon: animal (URL: https://drive.google.com/file/d/...)
✓ Added PNG icon: building (URL: https://drive.google.com/file/d/...)
Added 18 new PNG icons
Total icons after PNG extraction: 18
=== ICON EXTRACTION PHASE 2: SVG Sprite ===
No icons.svg file found, skipping SVG extraction
=== ICON EXTRACTION COMPLETE ===
Final icon count: 18
✓ Successfully extracted 18 icon(s)
=== ICON EXTRACTION PHASE 1: PNG Icons ===
No icons/ directory found, will try SVG sprite
=== ICON EXTRACTION PHASE 2: SVG Sprite ===
Processing icons.svg sprite file
✓ Extracted 5 icons from SVG sprite
✓ Added SVG icon: building (URL: https://drive.google.com/file/d/...)
✓ Added SVG icon: river (URL: https://drive.google.com/file/d/...)
Added 5 new SVG icons, skipped 0 (PNG priority)
=== ICON EXTRACTION COMPLETE ===
Final icon count: 5
✓ Successfully extracted 5 icon(s)
=== ICON EXTRACTION PHASE 1: PNG Icons ===
No icons/ directory found, will try SVG sprite
=== ICON EXTRACTION PHASE 2: SVG Sprite ===
No icons.svg file found, skipping SVG extraction
=== ICON EXTRACTION COMPLETE ===
Final icon count: 0
⚠️ PNG SPRITE DETECTED BUT CANNOT BE EXTRACTED
Google Apps Script cannot parse PNG sprites (icons.png)
Reason: No image processing libraries available
Options:
1. Use config with individual PNG files in icons/ directory
2. Use config with SVG sprite (icons.svg)
3. Contact support about external API for PNG extraction
Note: icons.json metadata detected but unusable without PNG extraction
Most mapeosettings files already include individual PNG files. These work perfectly.
Check if your file has individual PNGs:
- Extract the mapeosettings file
- Look for
icons/directory - If it contains PNG files → ✅ Will work
If your config has icons.svg, it will work with our recent fixes.
If you only have PNG sprites:
- Use
mapeo-settings-builderto rebuild config - Ensure it outputs individual PNG files or SVG sprite
- Or manually extract icons from PNG sprite using external tools
Create Node.js service:
// External API endpoint
const express = require('express');
const sharp = require('sharp');
app.post('/extract-png-sprite', async (req, res) => {
const { pngSprite, metadata } = req.body;
const icons = [];
for (const [name, coords] of Object.entries(metadata)) {
const extracted = await sharp(pngSprite)
.extract({
left: coords.x,
top: coords.y,
width: coords.width,
height: coords.height
})
.toBuffer();
icons.push({ name, data: extracted });
}
res.json({ icons });
});
Deployment: Vercel, Railway, Heroku, Google Cloud Functions
Integration:
// In Apps Script
function extractPngSpriteViaAPI(pngBlob, iconsJson) {
const response = UrlFetchApp.fetch('https://api.example.com/extract-png-sprite', {
method: 'post',
payload: {
pngSprite: pngBlob.getBytes(),
metadata: JSON.parse(iconsJson.getDataAsString())
}
});
const icons = JSON.parse(response.getContentText());
return icons;
}
Pros:
- ✅ Full PNG sprite support
- ✅ Can handle any image format
Cons:
- ❌ Requires hosting
- ❌ Network latency
- ❌ Additional costs
- ❌ Security considerations
Effort: 2-3 days development + deployment
Test File 1: mapeo-default-min.mapeosettings
- Has individual PNGs in
icons/directory (18 files) - Expected: All icons extracted successfully ✅
Test File 2: Custom config with SVG sprite only
- Has
icons.svgbut noicons/directory - Expected: SVG icons extracted successfully ✅
Test File 3: Config with PNG sprite only
- Has
icons.pngandicons.jsonbut no individual PNGs or SVG - Expected: Warning shown, no icons extracted
⚠️
- Import mapeosettings file
- Check console logs for extraction phase messages
- Verify Categories sheet column B has icon URLs
- Click icon URLs to confirm files accessible
- Check if icons display properly in Drive
A: Google Apps Script is a sandboxed JavaScript environment that doesn't allow installing Node.js packages or running external binaries. It only supports built-in Google services.
A: Google Vision API can analyze images but cannot crop/extract sub-regions. It's designed for AI/ML tasks (OCR, label detection), not image manipulation.
A: Google Apps Script doesn't have access to browser Canvas API. It runs server-side without DOM or Canvas.
A: Theoretically possible but extremely complex:
- Would need to implement full PNG decoder in JavaScript
- Would need to handle compression (zlib/deflate)
- Would need to re-encode extracted regions
- Effort: 2-3 weeks of development
- Performance: Very slow (JavaScript not optimized for this)
- Reliability: High risk of bugs
- Not recommended
A: Unlikely. Google Apps Script is designed for document automation, not image processing. Use external services for image tasks.
A: Yes! Most mapeosettings files include:
- Individual PNG files in
icons/directory ✅ - Or SVG sprite in
icons.svg✅ - PNG sprite is usually just an additional format
- ICON_PARSING_FIX.md - SVG sprite parsing improvements
- ICON_IMPORT_FIX.md - PNG file extraction from icons/ directory
- IMPORT_CAT.md - Overall import process documentation
| Format | Status | Notes |
|---|---|---|
Individual PNGs (icons/*.png) |
✅ Supported | Preferred format, works great |
SVG Sprite (icons.svg) |
✅ Supported | Works with recent fixes |
PNG Sprite (icons.png) |
❌ Not Supported | Requires external API |
Bottom Line: The import feature works for standard mapeosettings files. PNG sprite-only configs would need external API support (not currently implemented).