-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fdda365
Showing
6 changed files
with
800 additions
and
0 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,31 @@ | ||
{ | ||
"env": { | ||
"browser": true, | ||
"es6": true, | ||
"node": true | ||
}, | ||
"extends": "eslint:recommended", | ||
"parserOptions": { | ||
"ecmaVersion": 2018 | ||
}, | ||
"rules": { | ||
"indent": [ | ||
"error", | ||
4 | ||
], | ||
"linebreak-style": [ | ||
"error", | ||
"windows" | ||
], | ||
"quotes": [ | ||
"error", | ||
"double" | ||
], | ||
"semi": [ | ||
"error", | ||
"always" | ||
], | ||
"no-console": "off", | ||
"no-process-env": "off" | ||
} | ||
} |
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,64 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# Typescript v1 declaration files | ||
typings/ | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
|
||
# project-specific files | ||
pixelfix-macos-x64 | ||
pixelfix-linux-x64 | ||
pixelfix-win-x64.exe | ||
pixelfix-win-x86.exe |
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,20 @@ | ||
# Pixelfix | ||
|
||
Changes the colors of completely transparent pixels in an image to match the color of the nearest non-transparent pixel. | ||
|
||
Designed to be a quick drag-and-drop tool: | ||
|
||
1. Make your images | ||
2. Select them all and drag them on to the pixelfix executable. The pixelfix executable will overwrite the original images with fixed copies. | ||
3. Make sure there were no errors and close the console window | ||
4. Use or upload your images. Your images should now look fine when resized. | ||
|
||
## More info | ||
|
||
When saving an image file, most image editors will save completely transparent pixels as black. On some platforms, the resizing algorithm blends transparent pixels with non-transparent pixels, resulting in black edges on resized images. [Here](http://www.adriancourreges.com/blog/2017/05/09/beware-of-transparent-pixels/) is an article showing the difference and discussing techniques to fix the issue. | ||
|
||
This script keeps those pixels transparent, but changes their color to match the nearest non-transparent pixel. This means that when the non-transparent and transparent pixels are blended, there should be no color difference. | ||
|
||
This script is made into an executable using [the pkg tool](https://www.npmjs.com/package/pkg). | ||
|
||
`pkg -o pixelfix -t node10-win-x64,node10-win-x86,node10-macos-x64,node10-linux-x64 .\index.js` |
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,93 @@ | ||
"use strict"; | ||
|
||
const jimp = require("jimp"); | ||
const Delaunay = require("d3-delaunay").Delaunay; | ||
|
||
const neighborLocations = [ | ||
[-1, -1], | ||
[ 0, -1], | ||
[ 1, -1], | ||
[ 1, 0], | ||
[ 1, 1], | ||
[ 0, 1], | ||
[-1, 1], | ||
[-1, 0] | ||
]; | ||
|
||
let argsArray = process.argv.slice(2); | ||
|
||
console.log(argsArray); | ||
|
||
let dbgMode = false; | ||
|
||
for (let i = argsArray.length + 1; i >= 0; i--) { | ||
let arg = argsArray[i]; | ||
if (arg == "-d") { | ||
dbgMode = true; | ||
argsArray.splice(i, 1); | ||
} | ||
} | ||
|
||
if (process.argv.length < 3) { | ||
console.log("pixelfix \"path to file\" to fix transparent pixels in file"); | ||
console.log("pixelfix \"path to file\" \"path to file 2\" to fix transparent pixels in multiple files"); | ||
console.log("pixelfix -d \"path to file\" to view debug output (will overwrite file)"); | ||
return; | ||
} | ||
|
||
let promises = []; | ||
for (let fileLocation of argsArray) { | ||
promises.push((async function() { | ||
let image = await jimp.read(fileLocation); | ||
|
||
let voronoiPoints = []; | ||
let voronoiColors = []; | ||
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) { | ||
let alpha = this.bitmap.data[ idx + 3 ]; | ||
if (alpha != 0) { | ||
let red = this.bitmap.data[ idx + 0 ]; | ||
let green = this.bitmap.data[ idx + 1 ]; | ||
let blue = this.bitmap.data[ idx + 2 ]; | ||
// Voronoi | ||
for (let offset of neighborLocations) { | ||
let neighborAlpha = this.bitmap.data[image.getPixelIndex(x + offset[0], y + offset[1]) + 3]; | ||
if (neighborAlpha == 0) { | ||
voronoiPoints.push([x, y]); | ||
voronoiColors.push([red, green, blue]); | ||
break; | ||
} | ||
} | ||
} | ||
}); | ||
if (voronoiPoints.length > 0) { | ||
let dela = Delaunay.from(voronoiPoints); | ||
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) { | ||
let alpha = this.bitmap.data[ idx + 3 ]; | ||
if (alpha == 0) { | ||
let closestIndex = dela.find(x, y); | ||
if (closestIndex != -1) { | ||
let color = voronoiColors[closestIndex]; | ||
|
||
this.bitmap.data[ idx + 0 ] = color[0]; | ||
this.bitmap.data[ idx + 1 ] = color[1]; | ||
this.bitmap.data[ idx + 2 ] = color[2]; | ||
if (dbgMode) { | ||
this.bitmap.data[idx + 3] = 255; | ||
} | ||
} | ||
} | ||
}); | ||
await image.writeAsync(fileLocation); | ||
console.log(`Written to ${fileLocation}`); | ||
} else { | ||
console.log(`No transparent pixels to fix in ${fileLocation}`); | ||
} | ||
})()); | ||
} | ||
|
||
Promise.all(promises).then(() => { | ||
console.log("Press any key to exit"); | ||
process.stdin.setRawMode(true); | ||
process.stdin.resume(); | ||
process.stdin.on("data", process.exit.bind(process, 0)); | ||
}); |
Oops, something went wrong.