Last active
July 14, 2019 15:32
-
-
Save skybldev/42fcb189c3aa5545fd4830aa9a7c4f77 to your computer and use it in GitHub Desktop.
A JS wrapper for TheLastMillenial's TI-84+CE HDPICV image converter (version beta 2)
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
/** | |
* NAME: | |
* convpng.js - a JS wrapper for TheLastMillenial's TI-84+CE HDPICV image converter. | |
* SYNOPSIS: | |
* node convpng.js [OPTIONS] [SOURCE.png] | |
* DESCRIPTION: | |
* Since TLM is not as active on this project at the moment I decided to make a simple | |
* little wrapper for the old beta 2 version of the project. It requires Node.JS to be | |
* installed; apologies since JS is the language I am most proficient and fast with. | |
* Also, this only works on Windows. | |
* REQUIREMENTS: | |
* imagemagick https://imagemagick.org/ or package manager of choice | |
* nodejs https://nodejs.org/ or package manager of choice | |
* convpng specifically the windows_convpng.exe of beta 2 (v1.0.0-beta.2) here: | |
* https://github.com/TheLastMillennial/HD-Picture-Viewer/releases | |
* PARAMETERS: | |
* SOURCE.png [REQUIRED] the source image, unsplit and un-resized as this program | |
* uses imagemagick to do all that stuff. | |
* OPTIONS | |
* -a Appvar name. This is the calculator's version of a 'filename'. This | |
* script will automatically add 'L' or 'R' to it to signify which is | |
* the left or right half of the image. If not declared, it will be | |
* the same as the input filename shortened to the first 7 characters. | |
* NOTES: | |
* To make this script not too complicated and because I don't know how to implement | |
* space-separated argument vals, arguments are used like: -a=name, each argu- | |
* ment's val seprated by an equal. | |
* EXAMPLE: | |
* node convpng.js -a=FOREST forest.png | |
* The above example will process the image "forest.png", and output two appVars | |
* named "FORESTL.8xv" and "FORESTR.8xv" into the cwd. | |
* CREDITS: | |
* Thank you, Miller Medeiros for your brilliant shell helper module. Edited a bit for | |
* conciseness. | |
* https://gist.github.com/millermedeiros/4724047 | |
* used in func execSeries | |
* WARNING - THE FOLLOWING CODE IS VERY DIRTY AND MAY CAUSE HEADACHES; PROCEED WITH CAUTION. | |
*/ | |
var fs = require('fs'); | |
var chp = require('child_process'); | |
var input = process.argv.slice(2); // this trims off the first two elements we don't need. | |
var source; | |
var appVar = false; | |
var outHeader; | |
var execSeries = function(cmds, cb) { | |
var execNext = function() { | |
var parts = cmds.shift().split(/\s+/g); // splits by whitespaces. | |
var p = chp.spawn(parts[0], parts.slice(1), {stdio: 'inherit'}); | |
p.on('exit', (code) => { | |
var err; | |
if(code) { | |
err.code = code; | |
err.cmd = cmds.shift(); | |
cb(code); // cb = CallBack | |
} else if(cmds.length) { | |
execNext(); // recursion babyyyyy | |
} else { | |
cb(); | |
} | |
}); | |
}; | |
execNext(); | |
}; | |
var delMultiple = function(files, cb) { | |
for(i = 0; i < files.length; i++) { | |
try { // try..catch..finally will catch errors even in sync methods rather than callbacks | |
fs.unlinkSync(files[i]); | |
} catch(err) { | |
cb(err); | |
} finally { | |
cb(); // I know I shouldn't be callbacking multple times but who cares | |
} | |
} | |
}; | |
input.forEach((arg) => { | |
if(/-a=|-c|-o=/.test(arg)) { // a shortened form of "if the argument includes either of these" | |
var opt = arg.split('=')[0]; | |
var val = arg.split('=')[1]; | |
// Appvar option | |
if(opt == '-a' && val.length < 9) { | |
outHeader = val.toUpperCase(); | |
appVar = val.toUpperCase().substring(0, 7); // shorten to the first 7 chars | |
} else if(opt == '-a' && val.length > 8) { | |
throw "Error: AppVar name must only be up to 8 characters long."; | |
} | |
} else if(fs.existsSync(arg)) { // assume that the arg without the dash is the required one | |
source = arg; | |
if(!appVar) { | |
outHeader = arg.split('.')[0].toUpperCase().substring(0, 8); | |
appVar = outHeader.substring(0, 7); | |
} | |
} else { | |
throw "Error: Source image not found. Make sure it is in the same directory as the conving.exe!"; | |
} | |
}); | |
execSeries([ | |
`convert ${source} -resize 320x240 temp.png`, | |
'convert temp.png -crop 50%x100% crop_%d.png' | |
], (err) => { | |
if(err) throw `ImageMagick Error! Code ${err.code}`; | |
console.log('Successfully resized and split image.'); | |
fs.readFile('convpng.template', 'utf8', (err, data) => { | |
if(err) throw `Error reading convpng: ${err}`; | |
var side = 0; | |
console.log("Successfully read the convpng template."); | |
var convFinal = function(data, cb) { | |
var sideLtr = (side == 0) ? 'L' : 'R'; | |
var convIni = data | |
.replace(/@/g, `${side}`) | |
.replace('%', `${appVar}${sideLtr}`) | |
.replace('$', `${sideLtr}${outHeader.padEnd(8, '_')}`); | |
fs.writeFile('convpng.ini', convIni, 'utf8', (err) => { | |
if(err) throw `Error writing convpng: ${err}`; | |
console.log(`Successfully wrote ${sideLtr}-side convpng.ini.`); | |
chp.execFile('windows_convpng.exe', (err) => { | |
if(err) throw `Error executing convpng.exe: ${err}`; | |
console.log(`Successfully executed ${sideLtr}-side convpng.exe.`); | |
side++; | |
if(side == 1) { | |
convFinal(data); // recursion babyyyyy | |
} else { | |
delMultiple(['crop_0.png', 'crop_1.png', 'temp.png'], (err) => { | |
if(err) throw `Error cleaning up excess files: ${err}`; | |
}); | |
console.log('Done.'); | |
}; | |
}); | |
}); | |
}; | |
convFinal(data); | |
}); | |
}); |
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
#GroupICE : all_gfx | |
#Palette : xlibc | |
#PNGImages : | |
crop_@.png | |
#AppvarICE : % | |
#OutputHeader : HDPICV2$ | |
#PNGImages : | |
crop_@.png |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment