Un nouvel outil qui aide a réduire du pixel art magnifié 3x3 en pixel art qui est vraiment du pixel art.
L'avantage est de pouvoir le modifier dans un logiciel de pixel art, sauver un peu de mémoire et d'espace.
This commit is contained in:
6
tools/divise-texture-par-3/README.md
Normal file
6
tools/divise-texture-par-3/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
- Installe le D
|
||||
- `dub`
|
||||
|
||||
Ce programme sert à divier les texture par 3, et sort un masque de différence pour permettre de voir où la texture n'est pas strictement agrandie par 3, afin d'éviter les erreurs.
|
||||
|
||||
Ce programme ne réduit qu'une image dont chaque petit carré 3x3 contient la même couleur, et est aligné sur une coordonnée multiple de 3.
|
||||
15
tools/divise-texture-par-3/dub.json
Normal file
15
tools/divise-texture-par-3/dub.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "divise-texture-par-3",
|
||||
"description": "Remettre le pixel art en pixel!",
|
||||
"license": "BSL-1.0",
|
||||
|
||||
"dependencies":
|
||||
{
|
||||
"gamut": "~>3.0"
|
||||
},
|
||||
|
||||
"subConfigurations":
|
||||
{
|
||||
"gamut": "boost+mit"
|
||||
}
|
||||
}
|
||||
203
tools/divise-texture-par-3/source/main.d
Normal file
203
tools/divise-texture-par-3/source/main.d
Normal file
@@ -0,0 +1,203 @@
|
||||
module main;
|
||||
|
||||
import std.stdio;
|
||||
import std.json;
|
||||
import std.file;
|
||||
import std.conv;
|
||||
import std.string;
|
||||
import gamut;
|
||||
|
||||
void usage()
|
||||
{
|
||||
stderr.writeln();
|
||||
stderr.writeln("Divise-texture-par-3");
|
||||
stderr.writeln("l'indispensable outil de division par 3\n");
|
||||
stderr.writeln("usage: divise-texture-par-3 input.png output.png\n");
|
||||
stderr.writeln();
|
||||
stderr.writeln("Arguments:");
|
||||
stderr.writeln(" --help Shows this help.");
|
||||
stderr.writeln("A noter qu'un fichier diff.png est cree qui montre pourquoi on peut pas réduire par 3 en rouge.");
|
||||
}
|
||||
|
||||
|
||||
int main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
string input = null;
|
||||
string output = null;
|
||||
bool showHelp = false;
|
||||
|
||||
for(int i = 1; i < args.length; ++i)
|
||||
{
|
||||
string arg = args[i];
|
||||
if (arg == "-h" || arg == "--help")
|
||||
{
|
||||
showHelp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input)
|
||||
{
|
||||
if (output)
|
||||
throw new Exception("Too many files provided");
|
||||
else
|
||||
output = arg;
|
||||
}
|
||||
else
|
||||
input = arg;
|
||||
}
|
||||
}
|
||||
|
||||
if (showHelp || input is null || output is null)
|
||||
{
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
processFile(input, output, "diff.png");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
writefln("error: %s", e.message);
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Color
|
||||
{
|
||||
ubyte r, g, b, a;
|
||||
}
|
||||
|
||||
void processFile(string inputPath, string outputPath, string diffPath)
|
||||
{
|
||||
Image input;
|
||||
input.loadFromFile(inputPath);
|
||||
if (!input.isValid)
|
||||
throw new Exception("cant load " ~ inputPath);
|
||||
|
||||
input.convertTo(PixelType.rgba8);
|
||||
|
||||
if ( (input.width % 3) || (input.height % 3))
|
||||
throw new Exception("input is not a multiple of 3 in size");
|
||||
|
||||
int w = input.width;
|
||||
int h = input.height;
|
||||
int w3 = input.width / 3;
|
||||
int h3 = input.height / 3;
|
||||
|
||||
// show outlier pixels
|
||||
// compare each pixel with pixel at center of 3x3 patch, make it RED if not
|
||||
// else keep original color toned down 0.5x
|
||||
Image diff;
|
||||
diff.create(w, h, PixelType.rgba8);
|
||||
|
||||
bool successOfDownscale = true;
|
||||
|
||||
for(int y = 0; y < h; ++y)
|
||||
{
|
||||
Color[] scanInput = cast(Color[]) input.scanline(y);
|
||||
|
||||
Color[] scanDiff = cast(Color[]) diff.scanline(y);
|
||||
|
||||
// Copy input to diff, darkened
|
||||
for(int x = 0; x < w; ++x)
|
||||
{
|
||||
Color c = scanInput[x];
|
||||
c.r /= 2;
|
||||
c.g /= 2;
|
||||
c.b /= 2;
|
||||
scanDiff[x] = c;
|
||||
}
|
||||
|
||||
int refY = 1 + 3 * (y / 3);
|
||||
Color[] scanInputRef = cast(Color[]) input.scanline(refY);
|
||||
|
||||
for(int x = 0; x < w; ++x)
|
||||
{
|
||||
int refX = 1 + 3 * (x / 3);
|
||||
Color centerPixel = scanInputRef[refX];
|
||||
|
||||
Color thisPixel = scanInput[x];
|
||||
if (!isSameColor(thisPixel, centerPixel))
|
||||
{
|
||||
scanDiff[x] = Color(255, 0, 0, 255);
|
||||
successOfDownscale = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
scanDiff[x].g = 255; // green = OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!diff.saveToFile(diffPath))
|
||||
{
|
||||
throw new Exception("Couln't save " ~ diffPath);
|
||||
}
|
||||
|
||||
|
||||
// Output image
|
||||
|
||||
Image output;
|
||||
output.create(w3, h3, PixelType.rgba8);
|
||||
|
||||
// if the diff image isn't all black, there are errors that need to be fixed
|
||||
|
||||
// always create the divided by 3 image
|
||||
// this is just sampling in the middle
|
||||
for(int y = 0; y < h3; ++y)
|
||||
{
|
||||
Color[] scanInput = cast(Color[]) input.scanline(y*3);
|
||||
Color[] scanOutput = cast(Color[]) output.scanline(y);
|
||||
for(int x = 0; x < w3; ++x)
|
||||
{
|
||||
// Take the first pixel of the 3x3 patch that isn't fully transparent
|
||||
|
||||
Color found;
|
||||
for (int yy = 0; yy < 3; ++yy)
|
||||
{
|
||||
for (int xx = 0; xx < 3; ++xx)
|
||||
{
|
||||
Color c = (cast(Color[]) input.scanline(y*3+yy))[x*3+xx];
|
||||
if (c.a != 0)
|
||||
{
|
||||
found = c;
|
||||
goto okay;
|
||||
}
|
||||
}
|
||||
}
|
||||
okay:
|
||||
|
||||
|
||||
scanOutput[x] = found;
|
||||
}
|
||||
}
|
||||
|
||||
if (!output.saveToFile(outputPath))
|
||||
{
|
||||
throw new Exception("Couln't save " ~ outputPath);
|
||||
}
|
||||
|
||||
if (successOfDownscale)
|
||||
{
|
||||
writeln("SUCCESS");
|
||||
writeln("Image reduced by 3x, do not forget to use GIMP to make it palettized again!");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln("FAILURE");
|
||||
writeln("See diff.png for the problem in input image that prevents its reduction.");
|
||||
writeln("Not everything is align to 3x3 pixel patchs.");
|
||||
}
|
||||
}
|
||||
|
||||
bool isSameColor(Color a, Color b)
|
||||
{
|
||||
if ((a.a == 0) && (b.a == 0))
|
||||
return true; // do not check colors of transparent pixels
|
||||
else
|
||||
return a == b;
|
||||
}
|
||||
Reference in New Issue
Block a user