-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge control images into a single sprite sheet? #30
Comments
Looks really cool! thanks! I'll look more into it, when I have more time. |
Just tried it out. WOW! |
Free texture packer uses Max Rects Packer written in JS to get the images' position (x, y, w, h) in packed sprite sheet. So the sprite sheet and tcl code can be generated programmatically. I suggest using GitHub Actions to generate the sprite sheet and modified tcl code automatically then upload them as artifacts and I'm glad to make a pull request if you need. The problem is how can I replace the |
will you be updating the pypi package sv_ttk with this change? |
I need to investigate this a bit more, but then yes. |
My Node.js script to generate the sprite sheet (then compress with TinyPNG) and tcl code that replaces package.json{
"type": "module",
"dependencies": {
"maxrects-packer": "^2.7.3",
"sharp": "^0.30.5"
}
} pack.jsimport fs from 'fs';
import path from 'path';
import sharp from 'sharp';
import { MaxRectsPacker } from 'maxrects-packer';
for (const theme of ['dark', 'light']) {
const packer = new MaxRectsPacker(Infinity, Infinity, 0, {
pot: false,
square: true,
});
packer.addArray(await Promise.all(fs.readdirSync(theme).map(async f => {
const p = path.join(theme, f);
const { width, height } = await sharp(p).metadata();
const imagePath = path.join(theme, f);
return {
width,
height,
imagePath,
};
})));
const packedBin = packer.bins[0];
const packedImage = await sharp({
create: {
width: packedBin.width,
height: packedBin.height,
channels: 4,
background: 'transparent',
},
})
.composite(packedBin.rects.map(e => ({
input: e.imagePath,
left: e.x,
top: e.y,
})))
.png({
compressionLevel: 9,
})
.toBuffer();
try {
const shrinked = (await fetch('https://tinypng.com/web/shrink', {
method: 'post',
body: packedImage,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
'X-Forwarded-For': Array(4).fill().map(() => Math.floor(Math.random() * 256)).join('.'),
},
}).then(r => r.json())).output.url;
fs.writeFileSync(`${theme}.png`, Buffer.from((await fetch(shrinked).then(r => r.arrayBuffer()))));
} catch (err) {
console.log('Failed to minify with TinyPNG.', err);
fs.writeFileSync(`${theme}.png`, packedImage);
}
fs.writeFileSync(`${theme}.packed.tcl`, [
'variable images',
`variable s [image create photo -file [file join [file dirname [info script]] ${theme}.png] -format png]`,
`foreach {k x y w h} [list ${packedBin.rects.map(e => `${path.parse(e.imagePath).name} ${e.x} ${e.y} ${e.width} ${e.height}`).join(' ')}] {`,
' set images($k) [image create photo -width $w -height $h]',
' $images($k) copy $sprites -from $x $y [expr {$x+$w}] [expr {$y+$h}]',
'}',
'unset s',
].join('\n'));
} Generated tcl code example: variable images
variable s [image create photo -file [file join [file dirname [info script]] light.png] -format png]
foreach {k x y w h} [list card 0 0 50 50 notebook-border 50 0 40 40 ...] {
set images($k) [image create photo -width $w -height $h]
$images($k) copy $sprites -from $x $y [expr {$x+$w}] [expr {$y+$h}]
}
unset s |
@TransparentLC Just wanna let you know that this is almost finished together with some bugfixes, I just need to do some cleanup in the theme files, and then I'll make a new release. Probably I'll use this in my Azure and Forest theme as well. |
This will be an awesome update! Thanks both of you. |
Shit, I lost all my edits somewhere on my computer. I remember, it was in some totally random folder, and I didn't commit my changes, and now I can't find it. I'm so angry 🤬🤬🤬 |
Never mind, after 45 minutes of searching I found them inside the trash, deleted from |
@TransparentLC Huge thanks for all this! 👏🎉 Version 2 is now out: #47 |
This theme is really helpful to make a GUI application with modern style. I have already used it in my personal projects!
The theme's controls are made up of hundreds of png images, and I think that lots of tiny files might be a little unfriendly to hard drive and compression. So I tried to merge these images into a single sprite sheet (the following image) and it works great. This is a small enhancement and may be useful for distributing the theme with GUI applications since the users generally don't need to modify these images.
(I put the light and dark theme together)
merged.zip
The zip archive contains the following files:
sprites.png
The merged sprite sheet image. It can be created with TexturePacker (non-free) or Free texture packer (free and open-source).sprites.json
The sprite sheet image's metadata in "JSON (array)" format.extract.py
Reads the metadata and generates tcl code to load separate files from the sprite sheet. The code replacesload_images
.sun-valley.tcl
Modified tcl code.The text was updated successfully, but these errors were encountered: