Add --ignore-empty command line option (close #549)

This option can be used to avoid exporting empty frames/cels.
This commit is contained in:
David Capello 2014-11-30 10:23:11 -03:00
parent aee7eb7bd4
commit b7d86e596a
5 changed files with 61 additions and 7 deletions

View File

@ -210,6 +210,8 @@ void App::initialize(int argc, const char* argv[])
// Procress options
PRINTF("Processing options...\n");
bool ignoreEmpty = false;
// Open file specified in the command line
if (!options.values().empty()) {
Console console;
@ -258,6 +260,10 @@ void App::initialize(int argc, const char* argv[])
importLayer = value.value();
importLayerSaveAs = value.value();
}
// --ignore-empty
else if (opt == &options.ignoreEmpty()) {
ignoreEmpty = true;
}
// --save-as <filename>
else if (opt == &options.saveAs()) {
Document* doc = NULL;
@ -380,6 +386,9 @@ void App::initialize(int argc, const char* argv[])
if (m_exporter != NULL) {
PRINTF("Exporting sheet...\n");
if (ignoreEmpty)
m_exporter->setIgnoreEmptyCels(true);
m_exporter->exportSheet();
m_exporter.reset(NULL);
}

View File

@ -48,6 +48,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_sheetPack(m_po.add("sheet-pack").description("Use a packing algorithm to avoid waste of space\nin the texture"))
, m_splitLayers(m_po.add("split-layers").description("Import each layer of the next given sprite as\na separated image in the sheet"))
, m_importLayer(m_po.add("import-layer").requiresValue("<name>").description("Import just one layer of the next given sprite"))
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
, m_verbose(m_po.add("verbose").description("Explain what is being done"))
, m_help(m_po.add("help").mnemonic('?').description("Display this help and exits"))
, m_version(m_po.add("version").description("Output version information and exit"))

View File

@ -56,6 +56,7 @@ public:
const Option& sheetPack() const { return m_sheetPack; }
const Option& splitLayers() const { return m_splitLayers; }
const Option& importLayer() const { return m_importLayer; }
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
bool hasExporterParams() const;
@ -82,6 +83,7 @@ private:
Option& m_sheetPack;
Option& m_splitLayers;
Option& m_importLayer;
Option& m_ignoreEmpty;
Option& m_verbose;
Option& m_help;

View File

@ -32,6 +32,7 @@
#include "base/unique_ptr.h"
#include "gfx/packing_rects.h"
#include "gfx/size.h"
#include "raster/algorithm/shrink_bounds.h"
#include "raster/cel.h"
#include "raster/dithering_method.h"
#include "raster/image.h"
@ -205,6 +206,7 @@ DocumentExporter::DocumentExporter()
, m_texturePack(false)
, m_scale(1.0)
, m_scaleMode(DefaultScaleMode)
, m_ignoreEmptyCels(false)
{
}
@ -264,6 +266,7 @@ void DocumentExporter::exportSheet()
void DocumentExporter::captureSamples(Samples& samples)
{
ImageBufferPtr checkEmptyImageBuf;
std::vector<char> buf(32);
for (auto& item : m_documents) {
@ -289,7 +292,35 @@ void DocumentExporter::captureSamples(Samples& samples)
+ "." + base::get_file_extension(filename));
}
samples.addSample(Sample(doc, sprite, layer, frame, filename));
Sample sample(doc, sprite, layer, frame, filename);
if (m_ignoreEmptyCels) {
if (layer && layer->isImage() &&
!static_cast<LayerImage*>(layer)->getCel(frame)) {
// Empty cel this sample completely
continue;
}
base::UniquePtr<Image> checkEmptyImage(
Image::create(sprite->pixelFormat(),
sprite->width(),
sprite->height(),
checkEmptyImageBuf));
checkEmptyImage->setMaskColor(sprite->transparentColor());
clear_image(checkEmptyImage, sprite->transparentColor());
renderSample(sample, checkEmptyImage, 0, 0);
gfx::Rect frameBounds;
if (!algorithm::shrink_bounds(checkEmptyImage, frameBounds,
sprite->transparentColor())) {
// If shrink_bounds returns false, it's because the whole
// image is transparent (equal to the mask color).
continue;
}
}
samples.addSample(sample);
}
}
}
@ -355,12 +386,7 @@ void DocumentExporter::renderTexture(const Samples& samples, Image* textureImage
int x = sample.inTextureBounds().x - sample.trimmedBounds().x;
int y = sample.inTextureBounds().y - sample.trimmedBounds().y;
if (sample.layer()) {
layer_render(sample.layer(), textureImage, x, y, sample.frame());
}
else {
sample.sprite()->render(textureImage, x, y, sample.frame());
}
renderSample(sample, textureImage, x, y);
}
}
@ -415,4 +441,14 @@ void DocumentExporter::createDataFile(const Samples& samples, std::ostream& os,
<< "}\n";
}
void DocumentExporter::renderSample(const Sample& sample, raster::Image* dst, int x, int y)
{
if (sample.layer()) {
layer_render(sample.layer(), dst, x, y, sample.frame());
}
else {
sample.sprite()->render(dst, x, y, sample.frame());
}
}
} // namespace app

View File

@ -89,6 +89,10 @@ namespace app {
m_scaleMode = mode;
}
void setIgnoreEmptyCels(bool ignore) {
m_ignoreEmptyCels = ignore;
}
void addDocument(Document* document, raster::Layer* layer = NULL) {
m_documents.push_back(Item(document, layer));
}
@ -106,6 +110,7 @@ namespace app {
Document* createEmptyTexture(const Samples& samples);
void renderTexture(const Samples& samples, raster::Image* textureImage);
void createDataFile(const Samples& samples, std::ostream& os, raster::Image* textureImage);
void renderSample(const Sample& sample, raster::Image* dst, int x, int y);
class Item {
public:
@ -126,6 +131,7 @@ namespace app {
bool m_texturePack;
double m_scale;
ScaleMode m_scaleMode;
bool m_ignoreEmptyCels;
Items m_documents;
DISABLE_COPYING(DocumentExporter);