Skip to content

Instantly share code, notes, and snippets.

@AlexanderOMara
Last active November 30, 2019 23:57
Show Gist options
  • Save AlexanderOMara/ce16b3ab90d5373857d48fba7bf3de63 to your computer and use it in GitHub Desktop.
Save AlexanderOMara/ce16b3ab90d5373857d48fba7bf3de63 to your computer and use it in GitHub Desktop.
Node resedit replaceIconsForResource icon height issue
# OS files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
# Node files
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
report.*.json
*.tgz
yarn.lock
# Generated files
/LoadIconApp_HasIcon_updated.exe

Node resedit replaceIconsForResource icon height issue

Icons with an alpha mask have double the height in their bitmap info.

This height is different from the container height which should be used for icon groups.

The replaceIconsForResource funtion only use contained image data, and uses their values.

This results in the following output:

icons:
  ico: 0 0
  raw: 256 256

  ico: 128 128
  bmp: 128 256

  ico: 32 32
  bmp: 32 64

group:
  icon: 0 0
  icon: 128 0
  icon: 32 64

The following output would be the correct output:

icons:
  ico: 0 0
  raw: 256 256

  ico: 128 128
  bmp: 128 256

  ico: 32 32
  bmp: 32 64

group:
  icon: 0 0
  icon: 128 128
  icon: 32 32
#!/bin/bash
rm -rf icon.icoset
mkdir icon.icoset
convert -strip -resize 256x256 icon.png icon.icoset/icon_256x256.ico
convert -strip -resize 128x128 icon.png icon.icoset/icon_128x128.ico
convert -strip -resize 32x32 icon.png icon.icoset/icon_32x32.ico
convert \
icon.icoset/icon_256x256.ico \
icon.icoset/icon_128x128.ico \
icon.icoset/icon_32x32.ico \
icon.ico
rm -rf icon.icoset
'use strict';
const fs = require('fs');
const resedit = require('resedit');
async function main() {
const ico = resedit.Data.IconFile.from((fs.readFileSync('icon.ico')).buffer);
console.log('icons:');
for (const icon of ico.icons) {
console.log(' ico:', icon.width, icon.height);
const {data} = icon;
const {bitmapInfo} = data;
if (bitmapInfo) {
console.log(' bmp:', bitmapInfo.width, bitmapInfo.height);
}
else {
console.log(' raw:', data.width, data.height);
}
console.log('');
}
const exe = resedit.NtExecutable.from(fs.readFileSync('LoadIconApp_HasIcon.exe').buffer);
const res = resedit.NtExecutableResource.from(exe);
const replaceGroup = resedit.Resource.IconGroupEntry.fromEntries(res.entries)[0];
resedit.Resource.IconGroupEntry.replaceIconsForResource(
res.entries,
replaceGroup.id,
replaceGroup.lang,
ico.icons.map(icon => icon.data)
);
for (const group of resedit.Resource.IconGroupEntry.fromEntries(res.entries)) {
console.log('group:');
for (const icon of group.icons) {
console.log(' icon:', icon.width, icon.height);
}
console.log('');
}
res.outputResource(exe);
fs.writeFileSync('LoadIconApp_HasIcon_updated.exe', Buffer.from(exe.generate()));
}
main();
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"resedit": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resedit/-/resedit-0.2.1.tgz",
"integrity": "sha512-q7F7qgUIoomyQ3IPRxYkcHxs/1jAShCgBHUTdFQBeb5W7AqRN/1+Zs801E7Sk1a65uas9eQ7gsoIgO9PeyErQw=="
}
}
}
{
"private": true,
"dependencies": {
"resedit": "^0.2.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment