@pixra/ico-export 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/plugin.json +1 -1
- package/dist/plugin.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# ICO Export
|
|
2
2
|
|
|
3
|
-
A Pixra plugin that exports the current image as a
|
|
3
|
+
A Pixra plugin that exports the current image as a `.ico` file containing multiple sizes, suitable for website favicons.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- Generates a single `.ico` with common sizes (16/32
|
|
7
|
+
- Generates a single `.ico` with common sizes (16/32)
|
|
8
|
+
- Optimized for website favicons
|
|
8
9
|
- Preserves aspect ratio (centered with transparent padding)
|
|
9
10
|
- If there is an active selection, exports the selection area
|
|
10
11
|
|
package/dist/plugin.json
CHANGED
package/dist/plugin.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/plugin.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * ICO Export Plugin for Pixra\n *\n * Exports the current image as a
|
|
4
|
+
"sourcesContent": ["/**\n * ICO Export Plugin for Pixra\n *\n * Exports the current image as a .ico file for website favicons.\n * The generated .ico contains multiple PNG-based icon images.\n */\n\nimport * as pixra from '@pixra/plugin-sdk'\n\nconst ICON_SIZES = [16, 32] as const\n\nasync function resizeToSquarePng(\n imageData: ImageData,\n size: number,\n): Promise<ArrayBuffer> {\n const bitmap = await createImageBitmap(imageData)\n try {\n const canvas = new OffscreenCanvas(size, size)\n const ctx = canvas.getContext('2d')!\n\n // Clear to transparent\n ctx.clearRect(0, 0, size, size)\n\n // Contain: preserve aspect ratio and center\n const scale = Math.min(size / bitmap.width, size / bitmap.height)\n const drawWidth = Math.max(1, Math.round(bitmap.width * scale))\n const drawHeight = Math.max(1, Math.round(bitmap.height * scale))\n const offsetX = Math.round((size - drawWidth) / 2)\n const offsetY = Math.round((size - drawHeight) / 2)\n\n ctx.drawImage(bitmap, offsetX, offsetY, drawWidth, drawHeight)\n\n const blob = await canvas.convertToBlob({ type: 'image/png' })\n return await blob.arrayBuffer()\n } finally {\n bitmap.close()\n }\n}\n\nfunction writeIco(pngImages: ArrayBuffer[], sizes: number[]): ArrayBuffer {\n if (pngImages.length !== sizes.length) {\n throw new Error('writeIco: pngImages and sizes length mismatch')\n }\n\n const count = pngImages.length\n const headerSize = 6 + 16 * count\n const totalSize =\n headerSize + pngImages.reduce((sum, buf) => sum + buf.byteLength, 0)\n\n const out = new ArrayBuffer(totalSize)\n const view = new DataView(out)\n const outBytes = new Uint8Array(out)\n\n // ICONDIR\n view.setUint16(0, 0, true) // reserved\n view.setUint16(2, 1, true) // type: 1 = icon\n view.setUint16(4, count, true)\n\n let imageOffset = headerSize\n\n for (let i = 0; i < count; i++) {\n const size = sizes[i]\n const png = pngImages[i]\n const entryOffset = 6 + i * 16\n\n // ICONDIRENTRY\n view.setUint8(entryOffset + 0, size === 256 ? 0 : size) // width\n view.setUint8(entryOffset + 1, size === 256 ? 0 : size) // height\n view.setUint8(entryOffset + 2, 0) // color count\n view.setUint8(entryOffset + 3, 0) // reserved\n view.setUint16(entryOffset + 4, 1, true) // planes\n view.setUint16(entryOffset + 6, 32, true) // bit count\n view.setUint32(entryOffset + 8, png.byteLength, true) // bytes in resource\n view.setUint32(entryOffset + 12, imageOffset, true) // image offset\n\n outBytes.set(new Uint8Array(png), imageOffset)\n imageOffset += png.byteLength\n }\n\n return out\n}\n\nasync function exportIco(): Promise<void> {\n const activeImage = await pixra.workspace.getActiveImage()\n if (!activeImage) {\n await pixra.window.showErrorMessage('No image is currently open')\n return\n }\n\n await pixra.window.withProgress(\n { title: 'Exporting ICO...', cancellable: false },\n async (progress) => {\n const pngBuffers: ArrayBuffer[] = []\n const sizes = [...ICON_SIZES]\n\n for (let i = 0; i < sizes.length; i++) {\n const size = sizes[i]\n progress.report({\n message: `Rendering ${size}x${size}...`,\n percentage: (i / sizes.length) * 85,\n })\n pngBuffers.push(await resizeToSquarePng(activeImage, size))\n }\n\n progress.report({ message: 'Packaging .ico...', percentage: 90 })\n const ico = writeIco(pngBuffers, sizes)\n\n // Get the original filename from the active tab\n const activeTab = await pixra.tabs.getActive()\n const baseName = activeTab?.name.replace(/\\.[^.]+$/, '')\n if (!baseName) {\n throw new Error('Failed to determine base filename from active tab')\n }\n const filename = `${baseName}.ico`\n\n progress.report({ message: 'Saving file...', percentage: 98 })\n await pixra.window.saveFile({ filename, data: ico })\n\n await pixra.window.showInformationMessage(\n `Exported ICO (${sizes.join('/')})`,\n )\n },\n )\n}\n\nexport function activate(context: pixra.ExtensionContext) {\n const disposable = pixra.commands.registerCommand(\n 'icoExport.export',\n exportIco,\n )\n context.subscriptions.push(disposable)\n}\n\nexport function deactivate() {\n // Nothing to clean up\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixra/ico-export",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Export current image as a
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"description": "Export current image as a .ico file for website favicons (multi-size)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/rxliuli/pixra",
|