mirror of
https://github.com/aseprite/aseprite.git
synced 2024-11-20 14:21:45 +00:00
Fix Trim command when top-left corner is non-transparent (fix #1659)
This commit is contained in:
parent
536a4c5d3a
commit
695d85e566
@ -324,11 +324,59 @@ void DocApi::trimSprite(Sprite* sprite, const bool byGrid)
|
||||
|
||||
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
|
||||
render.renderSprite(image, sprite, frame);
|
||||
|
||||
// TODO configurable (what color pixel to use as "refpixel",
|
||||
// here we are using the top-left pixel by default)
|
||||
gfx::Rect frameBounds;
|
||||
if (doc::algorithm::shrink_bounds(image, frameBounds, get_pixel(image, 0, 0)))
|
||||
|
||||
// Before this fix, we did use the top-left corner pixel by default as "refColor" in
|
||||
// doc::algorithm::shrink_bounds(image, frameBounds, refColor).
|
||||
// Now, we are looking for one color whole border (i.e: solid color border)
|
||||
// searching on the sprite square contour.
|
||||
//
|
||||
// If the algorithm finds a transparentColor pixel on border frame,
|
||||
// automatically "refColor" turns to transparentColor and it goes directly to
|
||||
// shrink_bounds function.
|
||||
// If the borders don't contain transparentColor, the algorithm keeps checking:
|
||||
// It search for a solid color border (top border first), then it checks
|
||||
// the opposite border (bottom border), then:
|
||||
// 1- If the opposite border color is equal to the first border,
|
||||
// this color will be the "refColor".
|
||||
// 2- If the color of the opposite border is solid, BUT different to the first
|
||||
// border we have to trigger a dialog, delegating the choise to the user.
|
||||
// 3- If opposite border contains differents colors, we choose the first border color as
|
||||
// "refColor".
|
||||
// 4- It repeat analisys to sprite left and right columns pixels.
|
||||
// If no border has solid color, trimSprite do nothing.
|
||||
|
||||
bool skipTrim = false;
|
||||
bool analizeMoreBorders = true;
|
||||
color_t refColor = get_pixel(image, 0, 0);
|
||||
bool firstBorderIsSolidColor = true;
|
||||
bool secondBorderIsSolidColor = true;
|
||||
const color_t probableRefColor1 = refColor;
|
||||
const color_t probableRefColor2 = get_pixel(image, sprite->width() - 1, sprite->height() - 1);
|
||||
|
||||
if (analizeFrameSpritePixels(image, sprite, refColor,
|
||||
firstBorderIsSolidColor,
|
||||
secondBorderIsSolidColor, true)) {
|
||||
// Here, we know that analizeFrameSpritePixels did not find transparent pixels on top and bottom borders.
|
||||
if (!firstBorderIsSolidColor && secondBorderIsSolidColor)
|
||||
refColor = probableRefColor2;
|
||||
else if (firstBorderIsSolidColor && secondBorderIsSolidColor && probableRefColor1 != probableRefColor2) {
|
||||
// Both border are solids colors but different, so we have to trigger the dialog
|
||||
skipTrim = true;
|
||||
analizeMoreBorders = false;
|
||||
}
|
||||
if (analizeMoreBorders && analizeFrameSpritePixels(image, sprite, refColor,
|
||||
firstBorderIsSolidColor,
|
||||
secondBorderIsSolidColor, false)) {
|
||||
if (!firstBorderIsSolidColor && secondBorderIsSolidColor)
|
||||
refColor = probableRefColor2;
|
||||
else if (firstBorderIsSolidColor && secondBorderIsSolidColor && probableRefColor1 != probableRefColor2)
|
||||
// Both border are solids colors but different, so we have to trigger the dialog
|
||||
skipTrim = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipTrim && doc::algorithm::shrink_bounds(image, frameBounds, refColor))
|
||||
bounds = bounds.createUnion(frameBounds);
|
||||
|
||||
// TODO merge this code with the code in DocExporter::captureSamples()
|
||||
@ -351,6 +399,61 @@ void DocApi::trimSprite(Sprite* sprite, const bool byGrid)
|
||||
cropSprite(sprite, bounds);
|
||||
}
|
||||
|
||||
bool DocApi::analizeFrameSpritePixels(Image* image,
|
||||
const Sprite* sprite,
|
||||
color_t& refColor,
|
||||
bool& firstBorderIsSolidColor,
|
||||
bool& secondBorderIsSolidColor,
|
||||
bool topBottomLookUp) {
|
||||
firstBorderIsSolidColor = true;
|
||||
secondBorderIsSolidColor = true;
|
||||
int spriteW = sprite->width();
|
||||
int spriteH = sprite->height();
|
||||
const color_t probableRefColor1 = get_pixel(image, 0, 0);
|
||||
const color_t probableRefColor2 = get_pixel(image, spriteW - 1, spriteH - 1);
|
||||
if (!topBottomLookUp) {
|
||||
int aux = spriteW;
|
||||
spriteW = spriteH;
|
||||
spriteH = aux;
|
||||
}
|
||||
color_t currentPixel = 0;
|
||||
color_t transparentColor = sprite->transparentColor();
|
||||
|
||||
if (probableRefColor1 == transparentColor || probableRefColor2 == transparentColor) {
|
||||
refColor = transparentColor;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i=0; i < spriteW; i++) {
|
||||
if (topBottomLookUp)
|
||||
currentPixel = get_pixel(image, i, 0);
|
||||
else
|
||||
currentPixel = get_pixel(image, 0, i);
|
||||
if (currentPixel != probableRefColor1) {
|
||||
firstBorderIsSolidColor = false;
|
||||
if (currentPixel == transparentColor) {
|
||||
refColor = transparentColor;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i < spriteW; i++) {
|
||||
if (topBottomLookUp)
|
||||
currentPixel = get_pixel(image, i, spriteH - 1);
|
||||
else
|
||||
currentPixel = get_pixel(image, spriteH - 1, i);
|
||||
if (currentPixel != probableRefColor2) {
|
||||
secondBorderIsSolidColor = false;
|
||||
if (currentPixel == transparentColor) {
|
||||
refColor = transparentColor;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DocApi::addFrame(Sprite* sprite, frame_t newFrame)
|
||||
{
|
||||
copyFrame(sprite, newFrame-1, newFrame,
|
||||
|
@ -117,6 +117,12 @@ namespace app {
|
||||
void setPalette(Sprite* sprite, frame_t frame, const Palette* newPalette);
|
||||
|
||||
private:
|
||||
bool analizeFrameSpritePixels(Image* image,
|
||||
const Sprite* sprite,
|
||||
color_t& refColor,
|
||||
bool& firstBorderIsSolidColor,
|
||||
bool& secondBorderIsSolidColor,
|
||||
bool topBottomLookUp);
|
||||
void cropImageLayer(LayerImage* layer,
|
||||
const gfx::Rect& bounds,
|
||||
const bool trimOutside);
|
||||
|
Loading…
Reference in New Issue
Block a user