
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Texture Map Generator in pure JavaScript (TypeScript/NodeJS/Multithreading)
Texture Map Generator in TypeScript (MIT License)
images/textureMap0.png

texturePool.ts (TypeScript template result. See all templates or create your own (custom) template)
namespace Game {
// Statistics:
// - textures: 244
// - textureMaps: 8
const maps = [
{
url : "images/textureMap0.png",
width : 1664,
height : 512,
repeatX : false,
repeatY : false
}
];
export var texturePool = {
"star" : { map : maps[ 0 ], x : 256, y : 384, width : 128, height : 128, opaque : false, trim : { left : 0, right : 0, top : 0, bottom : 0 } },
"music" : { map : maps[ 0 ], x : 384, y : 384, width : 128, height : 128, opaque : false, trim : { left : 0, right : 0, top : 0, bottom : 0 } }
};
}
Texture Map Generator in pure JavaScript (TypeScript/NodeJS/Multi-threading) is image processing tool.
Install this module locally(into your project only) with the following command:
npm install texturer
Install this module globally with the following command:
npm install texturer -g
git clone https://github.com/igor-bezkrovny/texturer
cd texturer
npm install
npm run build
to clean-up project run
npm run clean
Run in folder with config.json (see example folder)
texturer
Process specified configuration file
texturer example/app/resources/config.json
var Texturer = require("<path to texturer src/index.js>"),
config = JSON.parse(require("fs").readFileSync("./config.json", "utf8"));
new Texturer().generate(config, function (error) {
if (error) {
console.trace("\x1B[91m" + error + "\x1B[39m");
process.exit(42);
} else {
process.exit(0);
}
}, null);
####Usage
To enable TinyPNG conversion you need to set "tiny-png" : true compress option for appropriate texture-map-task (see below)
note: all folders described below are relative to current working directory
| property | value |
|---|---|
| folders | specifies folders configuration (see below) |
| templates | array of template files to use (w/o path, e.g. [ "css.hbs", "js.hbs" ]) |
| task‑defaults | optional object with default values for optional copy options/texture-map options as defaults |
| copy‑tasks | optional array of copy tasks to perform |
| texture‑map‑tasks | optional array of texture-map tasks to perform |
| exclude | optional exclude regular expression. all matching files and folders will be excluded. global and case insensitive (flags "gi" are set). see Regular Expressions |
Images will be copied to destination folder or encoded into data URI without any processing, their width/height will be written into description file using template
| property | value |
|---|---|
| folder | folder with images. all images will be copied to the folders.source/folder folder |
| data‑uri | optional see below |
Images from appropriate folder will be packed into one "texture-map" image, trim and compress options will be applied
| property | value |
|---|---|
| folder | Folder with image files. All images from this folder recursively will be used to generate folders.target/folder folder |
| texture‑map‑file | optional, default: texture-map<incremental number>.png Texture map image (.png) file path and name |
| brute‑force‑time | optional, default: 0 Additional time for finding best(smallest) texture map (ms) |
| repeat-x | optional, default: false Combine images into vertical texture map to allow application to use background-repeat: repeat-x |
| repeat-y | optional, default: false Combine images into horizontal texture map to allow application to use background-repeat: repeat-y |
| grid-step | optional, default: 1 X and Y coordinate values of Images placed on texture map will be divisible by grid-step |
| padding-x | optional, default: 0 Minimal horizontal distance between Images inside Texture Map Image |
| padding-y | optional, default: 0 Minimal vertical distance between Images inside Texture Map Image |
| trim | optional see below |
| data‑uri | optional see below |
| compress | optional see below |
| dimensions | optional see below |
repeat-xnote: all images insidefolderfolder should have the same width
repeat-ynote: all images insidefolderfolder should have the same height
| property | value |
|---|---|
| source | resources folder from which all input folders with images taken |
| target | folder to which all generated textureMap files put. Also it receives folders with images that are just copied |
| images(index.html) | path to folders.target relative to index.html (server's root) |
for example, if source folder is
app/resourcesand target folder isapp/www/assets/images, and index.html is located inapp/www, images(index.html) will beassets/images
| property | value |
|---|---|
| enable | optional, default: true Create data URI by encoding image using base64 |
| max-size | optional, default: 32512 Max data URI string length. If encoded data URI string length is longer, general url instead of data URI will not be created |
| create‑image‑file‑anyway | optional, default: false Create output image file even in case data URI successfully created |
| property | value |
|---|---|
| tiny-png | optional, default: false Use TinyPNG service (see below) |
| property | value |
|---|---|
| enable | optional, default: true Enable image trimming. Note: export to css should be done without image trimming |
| alpha | optional, default: 0 Set fully-transparent alpha (A from RGBA) value to trim transparent pixels out from image. For example, alpha = 15 means that pixels with alpha <= 15 will be trimmed out of image to reduce texture map size |
| property | value |
|---|---|
| max-x | optional, default: 1920 Max texture-map image width |
| max-y | optional, default: 1080 Max texture-map image Height |
TinyPNG service does advanced lossy compression for PNG images that preserves full alpha transparency.
It is free of charge for convert up to 500 images per month. So, up to 500 texture maps, which often is more than enough.
#####Receive API key To use TinyPNG service you need to receive API key.
#####Add API key to your config.json
create (or edit) following section in config.json:
"tinypng-api-keys": [{
"used" : 0,
"month": 0,
"year" : 0,
"key" : "YOUR-RECEIVED-KEY"
}]
After first use of tinypng.com service this information will be updated with correct month/year/used values.
palette | null or palette options object (see below). Default: null
| option | description |
|---|---|
colors | # of colors in desired palette. colors number <= 256 will result in 8bit indexed png. |
quantizationMethod | histogram method, 2: min-population threshold within sub-regions; 1: global top-population Default: 2 |
ditheringKernel | dithering kernel name, see available kernels below. Default: null |
useSerpentineDitheringPattern | true - use serpentine dithering. Default: false |
minimumHueColors | # of colors per hue group to evaluate regardless of counts, to retain low-count hues |
=================
"FloydSteinberg""FalseFloydSteinberg""Stucki""Atkinson""Jarvis""Burkes""Sierra""TwoSierra""SierraLite"{
"folders" : {
"source" : "./",
"target" : "../source",
"images(index.html)" : "images"
},
"exclude" : ".*wl.*",
"templates" : [
"ts.hbs"
],
"task-defaults" : {
"brute-force-time" : 0,
"trim" : {
"enable" : true,
"alpha" : 0
},
"data-uri" : {
"enable" : true,
"max-size" : 32512,
"create-image-file-anyway" : false
},
"grid-step" : 1,
"padding-x" : 0,
"padding-y" : 0,
"compress" : {
"tiny-png" : false
}
},
"copy-tasks" : [
{
"folder" : "lviv-ukraine-backgrounds",
"data-uri" : {
"enable" : true,
"max-size" : 32512,
"create-image-file-anyway" : false
}
}
],
"texture-map-tasks" : [
{
"folder" : "creative-nerds-wooden-icons",
"texture-map-file" : "creative-nerds-wooden-icons.png",
"brute-force-time" : 0,
"grid-step" : 1,
"padding-x" : 0,
"padding-y" : 0,
"repeat-x" : false,
"repeat-y" : false,
"compress" : {
"tiny-png" : false
},
"data-uri" : {
"enable" : true,
"max-size" : 32768,
"create-image-file-anyway" : false
},
"trim" : {
"enable" : true,
"alpha" : 0
}
},
{
"folder" : "recursive",
"compression" : {
"tinypng" : false
}
},
{
"folder" : "buttons",
"repeat-x" : true
}
],
"tinypng-api-keys" : [
{
"used" : 22,
"month" : 8,
"year" : 2015,
"key" : "fjhdsajkfjdsahjfkhdsajfhjdsakhfjkdshajkh-"
}
]
}
Texturer uses Handlebars as templating engine and exports next variables:
maps variableContains Array of Texture Map descriptions, each description is an object with following properties:
| property | value |
|---|---|
| url | relative texture map image url |
| data-uri | data URI of texture map image or null |
| width | texture map image width |
| height | texture map image height |
| repeat-x | all textures in texture map are repeatable by X axis |
| repeat-y | all textures in texture map are repeatable by Y axis |
| is-last-item | decorative, used in templates to know if to/not to emit comma |
textures variableContains Array of Texture descriptions, each description is an object with following properties:
| property | value |
|---|---|
| id | original texture file name without extension |
| file | original texture file name |
| map-index | texture map image index in maps array |
| url | relative texture map image url (it is better to emit maps and use map-index instead of url) |
| data-uri | data URI of texture map image or null |
| x | x coordinate in texture map image |
| y | y coordinate in texture map image |
| width | width of image in texture map image |
| height | height of image in texture map image |
| real-width | real width (before trim applied) of original texture |
| real-height | real height (before trim applied) of original texture |
| trim | trim rectangle (left, right, top, bottom) - number of pixels trimmed from each side |
| opaque | is texture opaque |
| repeat-x | is texture repeatable by X axis |
| repeat-y | is texture repeatable by Y axis |
| is-last-item | decorative, used in templates to know if to/not to emit comma |
You need to add to config.json template file name as follows (see config.json format):
{
...
"templates" : [
"<path-to-template-file>/<template-file-name>.hbs"
]
...
}
templates/js.hbs
js/texturePool.js
// Statistics:
// - textures: {{textures.length}}
// - textureMaps: {{maps.length}}
var Game = Game || {};
(function(config) {
var maps = [{{#each maps}}
{
url : "{{#if data-uri}}{{data-uri}}{{else}}{{url}}{{/if}}",
width : {{width}},
height : {{height}},
repeatX : {{repeat-x}},
repeatY : {{repeat-y}}
}{{#unless is-last-item}}, {{/unless}}{{/each}}
];
config.texturePool = { {{#each textures}}
"{{id}}" : {
map : maps[{{map-index}}],
x : {{x}},
y : {{y}},
width : {{real-width}},
height : {{real-height}},
opaque : {{opaque}},
trim : { left : {{trim.left}}, right : {{trim.right}}, top : {{trim.top}}, bottom : {{trim.bottom}} }
}{{#unless is-last-item}}, {{/unless}}{{/each}}
};
})(Game.config = Game.config || {});
integrate with image-quantization-library
interlaced jpeg decoding (?)
ability to work only in memory without writing files to disk. usable for ui tools
task-defaults was not useddata-uri instead of dataURItemplates array may now contain relative to config.json path and absolute path to template file.hbs, however Handlebars is still usednpm run clean - clean script added to package.jsonbin/texturer is now has optional parameter - config.json file namealpha-threshold property added to compression optionsfilter config.json property name changed to excludetemplates config.json propertyopaque property added to output templates (true if texture has no pixels with alpha)disable-trim is added to compression optionstexturer module from code####Example Images were taken from:
####Palette Quantization
NeuQuant with alpha: https://github.com/stuart/pngnq/blob/master/src/neuquant32.c (ported to JavaScript, need more work...)
RgbQuant with alpha: https://github.com/leeoniya/RgbQuant.js, modified to support alpha channel
TinyPNG.com sevice: https://tinypng.com, API implemented
####Image decoders/encoders:
node-png: https://github.com/leogiese/node-png (version "0.4.3" is used, but adopted to be able to save to 8bit png. Also implemented ability to reduce number of colors even for 32bit png)
bmp-js: https://www.npmjs.org/package/bmp-js (fixed issues with 8bit indexed colorType read)
TODO texturer now use child_process.fork instead of cluster module TODO check current node-webkit version
Due to issues in node-webkit you will need to do some additional steps:
var path = require("path");
process.execPath = path.join(path.dirname(process.execPath), '..', 'folder_with_node_exe', 'node.exe');
silent attribute to truecluster.setupMaster({
'exec': __dirname + '/worker.js',
'silent': true
});
FAQs
Texture Map Generator in pure JavaScript (TypeScript/NodeJS/Multithreading)
We found that texturer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.