-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(graph-layers): Clean up lint and tsc errors for pack-images script
- Loading branch information
1 parent
a97ca5f
commit ae61618
Showing
12 changed files
with
765 additions
and
615 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/** | ||
* Generate texture atlas from images | ||
* ``` | ||
* # default input/output | ||
* npx tsx ./pack-marker-images.ts | ||
* | ||
* # custom input/output directories | ||
* npx tsx ./pack-marker-images.ts [inputDir] [outputDir] | ||
* ``` | ||
*/ | ||
|
||
import {readFile, writeFile, readdir} from 'node:fs/promises'; | ||
import {dirname, join, resolve} from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
import ndarray, {NdArray} from 'ndarray'; | ||
import {getPixels, savePixels} from 'ndarray-pixels'; | ||
import pack from 'bin-pack'; | ||
import Datauri from 'datauri'; | ||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
const packageRoot = join(__dirname, '..'); | ||
|
||
const inputDir = process.argv[2] || 'src/layers/common-layers/marker-layer/markers/'; | ||
const outputDir = process.argv[3] || 'src/layers/common-layers/marker-layer/'; | ||
|
||
const INPUT_DIR = resolve(packageRoot, inputDir); | ||
const OUTPUT_IMAGE = resolve(packageRoot, outputDir, 'marker-atlas.png'); | ||
const OUTPUT_MAPPING = resolve(packageRoot, outputDir, `marker-mapping.ts`); | ||
const OUTPUT_DATA_URL = resolve(packageRoot, outputDir, 'atlas-data-url.ts'); | ||
const OUTPUT_LIST = resolve(packageRoot, outputDir, 'marker-list.ts'); | ||
const IMAGE_PATTERN = /\.(png|jpg|jpeg|gif|bmp|tiff)$/i; | ||
|
||
// Get all images in the input path | ||
const fileNames = (await readdir(INPUT_DIR)).filter((name) => IMAGE_PATTERN.test(name)); | ||
|
||
Promise.all(fileNames.map((name: string) => readImage(resolve(INPUT_DIR, name)))).then(async (images) => { | ||
// Images are loaded | ||
const nodes = images.map((pixels: NdArray, index: number) => ({ | ||
name: fileNames[index], | ||
pixels, | ||
width: pixels.shape[0], | ||
height: pixels.shape[1] | ||
})); | ||
|
||
// Bin pack | ||
const result = pack(nodes); | ||
// console.log(result.items.length + ' items packed.'); | ||
|
||
// Convert to texture atlas | ||
const outputJSON = {}; | ||
const outputImage = createImage(result.width, result.height); | ||
result.items.forEach((item) => { | ||
outputJSON[item.item.name.replace(IMAGE_PATTERN, '')] = { | ||
x: item.x, | ||
y: item.y, | ||
width: item.width, | ||
height: item.height, | ||
mask: true | ||
}; | ||
copyPixels(item.item.pixels, outputImage, item.x, item.y); | ||
}); | ||
|
||
// Write to disk | ||
await writeMapping(OUTPUT_MAPPING, outputJSON); | ||
await writeImage(OUTPUT_IMAGE, outputImage, () => writeDataURL(OUTPUT_IMAGE, OUTPUT_DATA_URL)); | ||
await writeList(OUTPUT_LIST, outputJSON); | ||
}); | ||
|
||
/* Utils */ | ||
|
||
function copyPixels(fromImage: NdArray, toImage: NdArray, x: number, y: number): void { | ||
const width = fromImage.shape[0]; | ||
const height = fromImage.shape[1]; | ||
const channels = fromImage.shape[2]; | ||
|
||
for (let i = 0; i < width; i++) { | ||
for (let j = 0; j < height; j++) { | ||
for (let k = 0; k < channels; k++) { | ||
const value = fromImage.get(i, j, k); | ||
toImage.set(i + x, j + y, k, value); | ||
} | ||
} | ||
} | ||
} | ||
|
||
async function writeMapping(filePath: string, content: unknown): Promise<void> { | ||
await exportJSFile(filePath, 'MarkerMapping', JSON.stringify(content, null, 2)); | ||
} | ||
|
||
function createImage(width: number, height: number): NdArray<Uint8ClampedArray> { | ||
return ndarray(new Uint8ClampedArray(width * height * 4), [width, height, 4]); | ||
} | ||
|
||
async function writeDataURL(imagePath: string, outputFilePath: string): Promise<void> { | ||
const content = {dataURL: await Datauri(imagePath)}; | ||
await exportJSFile(outputFilePath, 'AtlasDataURL', JSON.stringify(content, null, 2)); | ||
} | ||
|
||
async function writeList(filePath: string, content: object): Promise<void> { | ||
const markers = Object.keys(content); | ||
const markerMap = markers.reduce((res, marker) => { | ||
res[marker] = marker; | ||
return res; | ||
}, {}); | ||
const contentStr = JSON.stringify(markerMap, null, 2); | ||
await exportJSFile(filePath, 'MarkerList', contentStr); | ||
} | ||
|
||
async function exportJSFile(filePath: string, exportName: string, contentStr: string): Promise<void> { | ||
await writeFile( | ||
filePath, | ||
`/* eslint-disable */\nexport const ${exportName} = ${contentStr};\n/* eslint-enable */\n` | ||
); | ||
} | ||
|
||
async function readImage(filePath: string): Promise<NdArray> { | ||
return readFile(filePath).then((buffer) => getPixels(buffer, 'image/png')); | ||
} | ||
|
||
async function writeImage(filePath: string, pixelArr: NdArray<Uint8ClampedArray>, createDataURL: () => void): Promise<void> { | ||
await writeFile(filePath, await savePixels(pixelArr, 'image/png')); | ||
createDataURL(); | ||
} |
3 changes: 1 addition & 2 deletions
3
modules/graph-layers/src/layers/common-layers/marker-layer/atlas-data-url.ts
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file modified
BIN
-17.3 KB
(58%)
modules/graph-layers/src/layers/common-layers/marker-layer/marker-atlas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion
1
modules/graph-layers/src/layers/common-layers/marker-layer/marker-layer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
// @noflow | ||
import {CompositeLayer} from '@deck.gl/core'; | ||
import {IconLayer} from '@deck.gl/layers'; | ||
|
||
|
120 changes: 60 additions & 60 deletions
120
modules/graph-layers/src/layers/common-layers/marker-layer/marker-list.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,64 @@ | ||
/* eslint-disable */ | ||
export const MarkerList = { | ||
'location-marker-filled': 'location-marker-filled', | ||
'bell-filled': 'bell-filled', | ||
'bookmark-filled': 'bookmark-filled', | ||
bookmark: 'bookmark', | ||
'cd-filled': 'cd-filled', | ||
cd: 'cd', | ||
checkmark: 'checkmark', | ||
'circle-check-filled': 'circle-check-filled', | ||
'circle-check': 'circle-check', | ||
'circle-filled': 'circle-filled', | ||
'circle-i-filled': 'circle-i-filled', | ||
'circle-i': 'circle-i', | ||
'circle-minus-filled': 'circle-minus-filled', | ||
'circle-minus': 'circle-minus', | ||
'circle-plus-filled': 'circle-plus-filled', | ||
'circle-plus': 'circle-plus', | ||
'circle-questionmark-filled': 'circle-questionmark-filled', | ||
'circle-questionmark': 'circle-questionmark', | ||
'circle-slash-filled': 'circle-slash-filled', | ||
'circle-slash': 'circle-slash', | ||
'circle-x-filled': 'circle-x-filled', | ||
'circle-x': 'circle-x', | ||
circle: 'circle', | ||
'diamond-filled': 'diamond-filled', | ||
diamond: 'diamond', | ||
'flag-filled': 'flag-filled', | ||
flag: 'flag', | ||
gear: 'gear', | ||
'heart-filled': 'heart-filled', | ||
heart: 'heart', | ||
bell: 'bell', | ||
'location-marker': 'location-marker', | ||
'octagonal-star-filled': 'octagonal-star-filled', | ||
'octagonal-star': 'octagonal-star', | ||
'person-filled': 'person-filled', | ||
person: 'person', | ||
'pin-filled': 'pin-filled', | ||
pin: 'pin', | ||
'plus-small': 'plus-small', | ||
plus: 'plus', | ||
'rectangle-filled': 'rectangle-filled', | ||
rectangle: 'rectangle', | ||
'star-filled': 'star-filled', | ||
star: 'star', | ||
'tag-filled': 'tag-filled', | ||
tag: 'tag', | ||
'thumb-down-filled': 'thumb-down-filled', | ||
'thumb-down': 'thumb-down', | ||
'thumb-up': 'thumb-up', | ||
'thumb_up-filled': 'thumb_up-filled', | ||
'triangle-down-filled': 'triangle-down-filled', | ||
'triangle-down': 'triangle-down', | ||
'triangle-left-filled': 'triangle-left-filled', | ||
'triangle-left': 'triangle-left', | ||
'triangle-right-filled': 'triangle-right-filled', | ||
'triangle-right': 'triangle-right', | ||
'triangle-up-filled': 'triangle-up-filled', | ||
'triangle-up': 'triangle-up', | ||
'x-small': 'x-small', | ||
x: 'x' | ||
"bell-filled": "bell-filled", | ||
"bell": "bell", | ||
"bookmark-filled": "bookmark-filled", | ||
"bookmark": "bookmark", | ||
"cd-filled": "cd-filled", | ||
"cd": "cd", | ||
"checkmark": "checkmark", | ||
"circle-check-filled": "circle-check-filled", | ||
"circle-check": "circle-check", | ||
"circle-filled": "circle-filled", | ||
"circle-i-filled": "circle-i-filled", | ||
"circle-i": "circle-i", | ||
"circle-minus-filled": "circle-minus-filled", | ||
"circle-minus": "circle-minus", | ||
"circle-plus-filled": "circle-plus-filled", | ||
"circle-plus": "circle-plus", | ||
"circle-questionmark-filled": "circle-questionmark-filled", | ||
"circle-questionmark": "circle-questionmark", | ||
"circle-slash-filled": "circle-slash-filled", | ||
"circle-slash": "circle-slash", | ||
"circle-x-filled": "circle-x-filled", | ||
"circle-x": "circle-x", | ||
"circle": "circle", | ||
"diamond-filled": "diamond-filled", | ||
"diamond": "diamond", | ||
"flag-filled": "flag-filled", | ||
"flag": "flag", | ||
"gear": "gear", | ||
"heart-filled": "heart-filled", | ||
"heart": "heart", | ||
"location-marker-filled": "location-marker-filled", | ||
"location-marker": "location-marker", | ||
"octagonal-star-filled": "octagonal-star-filled", | ||
"octagonal-star": "octagonal-star", | ||
"person-filled": "person-filled", | ||
"person": "person", | ||
"pin-filled": "pin-filled", | ||
"pin": "pin", | ||
"plus-small": "plus-small", | ||
"plus": "plus", | ||
"rectangle-filled": "rectangle-filled", | ||
"rectangle": "rectangle", | ||
"star-filled": "star-filled", | ||
"star": "star", | ||
"tag-filled": "tag-filled", | ||
"tag": "tag", | ||
"thumb-down-filled": "thumb-down-filled", | ||
"thumb-down": "thumb-down", | ||
"thumb-up": "thumb-up", | ||
"thumb_up-filled": "thumb_up-filled", | ||
"triangle-down-filled": "triangle-down-filled", | ||
"triangle-down": "triangle-down", | ||
"triangle-left-filled": "triangle-left-filled", | ||
"triangle-left": "triangle-left", | ||
"triangle-right-filled": "triangle-right-filled", | ||
"triangle-right": "triangle-right", | ||
"triangle-up-filled": "triangle-up-filled", | ||
"triangle-up": "triangle-up", | ||
"x-small": "x-small", | ||
"x": "x" | ||
}; | ||
/* eslint-enable */ |
Oops, something went wrong.