Use rendered images to create optimized palette in render::create_palette_from_rgb()

This commit is contained in:
David Capello 2015-05-21 10:17:59 -03:00
parent 13ac74f37a
commit 85d638097b
4 changed files with 28 additions and 40 deletions

View File

@ -64,7 +64,7 @@ void ColorQuantizationCommand::onExecute(Context* context)
int n = entries.picks();
Palette palette(frame, n);
render::create_palette_from_rgb(sprite, frame, &palette);
render::create_palette_from_rgb(sprite, 0, sprite->lastFrame(), &palette);
Palette newPalette(*get_current_palette());

View File

@ -706,18 +706,18 @@ void fop_post_load(FileOp* fop)
return;
}
if (fop->document->sprite() != NULL) {
Sprite* sprite = fop->document->sprite();
if (sprite) {
// Creates a suitable palette for RGB images
if (fop->document->sprite()->pixelFormat() == IMAGE_RGB &&
fop->document->sprite()->getPalettes().size() <= 1 &&
fop->document->sprite()->palette(frame_t(0))->isBlack()) {
base::SharedPtr<Palette> palette
(render::create_palette_from_rgb(
fop->document->sprite(),
frame_t(0), NULL));
if (sprite->pixelFormat() == IMAGE_RGB &&
sprite->getPalettes().size() <= 1 &&
sprite->palette(frame_t(0))->isBlack()) {
base::SharedPtr<Palette> palette(
render::create_palette_from_rgb(
sprite, frame_t(0), sprite->lastFrame(), nullptr));
fop->document->sprite()->resetPalettes();
fop->document->sprite()->setPalette(palette.get(), false);
sprite->resetPalettes();
sprite->setPalette(palette.get(), false);
}
}

View File

@ -43,43 +43,30 @@ static Image* ordered_dithering(
Palette* create_palette_from_rgb(
const Sprite* sprite,
frame_t frameNumber,
frame_t fromFrame,
frame_t toFrame,
Palette* palette)
{
PaletteOptimizer optimizer;
if (!palette)
palette = new Palette(frame_t(0), Palette::MaxColors);
palette = new Palette(fromFrame, Palette::MaxColors);
bool has_background_layer = (sprite->backgroundLayer() != NULL);
ImagesCollector images(
sprite->folder(), // All layers
frameNumber, // Ignored, we'll use all frames
true, // All frames,
false); // forWrite=false, read only
bool has_background_layer = (sprite->backgroundLayer() != nullptr);
// Add a flat image with the current sprite's frame rendered
ImageRef flat_image(Image::create(sprite->pixelFormat(),
ImageRef flat_image(Image::create(IMAGE_RGB,
sprite->width(), sprite->height()));
render::Render().renderSprite(flat_image.get(), sprite, frameNumber);
// Create an array of images
std::vector<Image*> image_array;
std::map<ObjectId, Image*> used_images;
for (auto it=images.begin(); it!=images.end(); ++it) {
Image* image = it->image();
ObjectId imageId = image->id();
if (used_images.find(imageId) == used_images.end()) {
used_images.insert(std::make_pair(imageId, image));
image_array.push_back(image);
// Feed the optimizer with all rendered frames
render::Render render;
for (frame_t frame=fromFrame; frame<=toFrame; ++frame) {
render.renderSprite(flat_image.get(), sprite, frame);
optimizer.feedWithImage(flat_image.get());
}
}
image_array.push_back(flat_image.get());
// Generate an optimized palette for all images
create_palette_from_images(image_array, palette, has_background_layer);
// Generate an optimized palette
optimizer.calculate(palette, has_background_layer);
return palette;
}

View File

@ -1,5 +1,5 @@
// Aseprite Rener Library
// Copyright (c) 2001-2014 David Capello
// Copyright (c) 2001-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -43,7 +43,8 @@ namespace render {
// Creates a new palette suitable to quantize the given RGB sprite to Indexed color.
Palette* create_palette_from_rgb(
const Sprite* sprite,
frame_t frameNumber,
frame_t fromFrame,
frame_t toFrame,
Palette* newPalette); // Can be NULL to create a new palette
// Changes the image pixel format. The dithering method is used only