mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-11 13:14:17 +00:00
HueSaturation can be used for palette and pixels on indexed images now
If there are an active selection: we adjust pixels, if there is no selection, we adjust palette entries.
This commit is contained in:
parent
4834ff3320
commit
85b7996e9a
@ -431,4 +431,10 @@ void FilterManagerImpl::restoreSpritePalette()
|
||||
m_site.sprite()->setPalette(m_oldPalette.get(), false);
|
||||
}
|
||||
|
||||
bool FilterManagerImpl::isMaskActive() const
|
||||
{
|
||||
return static_cast<const app::Document*>(m_site.document())
|
||||
->isMaskVisible();
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -104,6 +104,7 @@ namespace app {
|
||||
int x() const override { return m_bounds.x; }
|
||||
int y() const override { return m_bounds.y+m_row; }
|
||||
bool isFirstRow() const override { return m_row == 0; }
|
||||
bool isMaskActive() const override;
|
||||
|
||||
// FilterIndexedData implementation
|
||||
const doc::Palette* getPalette() const override;
|
||||
|
@ -73,6 +73,10 @@ namespace filters {
|
||||
// to the palette in the first row.
|
||||
virtual bool isFirstRow() const = 0;
|
||||
|
||||
// Returns true if the mask is actived (so we are applying the
|
||||
// filter just to a part of the sprite).
|
||||
virtual bool isMaskActive() const = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace filters
|
||||
|
@ -64,50 +64,17 @@ void HueSaturationFilter::applyToRgba(FilterManager* filterMgr)
|
||||
uint32_t* dst_address = (uint32_t*)filterMgr->getDestinationAddress();
|
||||
const int w = filterMgr->getWidth();
|
||||
const Target target = filterMgr->getTarget();
|
||||
int x, c, r, g, b, a;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
for (int x=0; x<w; x++) {
|
||||
if (filterMgr->skipPixel()) {
|
||||
++src_address;
|
||||
++dst_address;
|
||||
continue;
|
||||
}
|
||||
|
||||
c = *(src_address++);
|
||||
|
||||
r = rgba_getr(c);
|
||||
g = rgba_getg(c);
|
||||
b = rgba_getb(c);
|
||||
a = rgba_geta(c);
|
||||
|
||||
{
|
||||
gfx::Hsl hsl(gfx::Rgb(r, g, b));
|
||||
|
||||
double h = hsl.hue() + m_h;
|
||||
while (h < 0.0)
|
||||
h += 360.0;
|
||||
h = std::fmod(h, 360.0);
|
||||
|
||||
double s = hsl.saturation() + m_s;
|
||||
s = MID(0.0, s, 1.0);
|
||||
|
||||
double l = hsl.lightness() + m_l;
|
||||
l = MID(0.0, l, 1.0);
|
||||
|
||||
hsl.hue(h);
|
||||
hsl.saturation(s);
|
||||
hsl.lightness(l);
|
||||
gfx::Rgb rgb(hsl);
|
||||
|
||||
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
||||
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
||||
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
||||
|
||||
if (a && (target & TARGET_ALPHA_CHANNEL))
|
||||
a = MID(0, a+m_a, 255);
|
||||
}
|
||||
|
||||
*(dst_address++) = rgba(r, g, b, a);
|
||||
color_t c = *(src_address++);
|
||||
applyHslFilterToRgb(target, c);
|
||||
*(dst_address++) = c;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,19 +84,17 @@ void HueSaturationFilter::applyToGrayscale(FilterManager* filterMgr)
|
||||
uint16_t* dst_address = (uint16_t*)filterMgr->getDestinationAddress();
|
||||
const int w = filterMgr->getWidth();
|
||||
const Target target = filterMgr->getTarget();
|
||||
int x, c, k, a;
|
||||
|
||||
for (x=0; x<w; x++) {
|
||||
for (int x=0; x<w; x++) {
|
||||
if (filterMgr->skipPixel()) {
|
||||
++src_address;
|
||||
++dst_address;
|
||||
continue;
|
||||
}
|
||||
|
||||
c = *(src_address++);
|
||||
|
||||
k = graya_getv(c);
|
||||
a = graya_geta(c);
|
||||
color_t c = *(src_address++);
|
||||
int k = graya_getv(c);
|
||||
int a = graya_geta(c);
|
||||
|
||||
{
|
||||
gfx::Hsl hsl(gfx::Rgb(k, k, k));
|
||||
@ -152,62 +117,87 @@ void HueSaturationFilter::applyToGrayscale(FilterManager* filterMgr)
|
||||
|
||||
void HueSaturationFilter::applyToIndexed(FilterManager* filterMgr)
|
||||
{
|
||||
if (!filterMgr->isFirstRow())
|
||||
return;
|
||||
|
||||
FilterIndexedData* fid = filterMgr->getIndexedData();
|
||||
const Target target = filterMgr->getTarget();
|
||||
FilterIndexedData* fid = filterMgr->getIndexedData();
|
||||
const Palette* pal = fid->getPalette();
|
||||
PalettePicks picks = fid->getPalettePicks();
|
||||
Palette* newPal = fid->getNewPalette();
|
||||
|
||||
int i = 0;
|
||||
for (bool state : picks) {
|
||||
if (!state) {
|
||||
// Apply filter to color palette
|
||||
if (!filterMgr->isMaskActive()) {
|
||||
if (!filterMgr->isFirstRow())
|
||||
return;
|
||||
|
||||
PalettePicks picks = fid->getPalettePicks();
|
||||
Palette* newPal = fid->getNewPalette();
|
||||
|
||||
int i = 0;
|
||||
for (bool state : picks) {
|
||||
if (!state) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
color_t c = pal->getEntry(i);
|
||||
applyHslFilterToRgb(target, c);
|
||||
newPal->setEntry(i, c);
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Apply filter to color region
|
||||
else {
|
||||
const RgbMap* rgbmap = fid->getRgbMap();
|
||||
const uint8_t* src_address = (uint8_t*)filterMgr->getSourceAddress();
|
||||
uint8_t* dst_address = (uint8_t*)filterMgr->getDestinationAddress();
|
||||
const int w = filterMgr->getWidth();
|
||||
|
||||
color_t c = pal->getEntry(i);
|
||||
int r = rgba_getr(c);
|
||||
int g = rgba_getg(c);
|
||||
int b = rgba_getb(c);
|
||||
int a = rgba_geta(c);
|
||||
for (int x=0; x<w; x++) {
|
||||
if (filterMgr->skipPixel()) {
|
||||
++src_address;
|
||||
++dst_address;
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
gfx::Hsl hsl(gfx::Rgb(r, g, b));
|
||||
|
||||
double h = hsl.hue() + m_h;
|
||||
while (h < 0.0) h += 360.0;
|
||||
h = std::fmod(h, 360.0);
|
||||
|
||||
double s = hsl.saturation() + m_s;
|
||||
s = MID(0.0, s, 1.0);
|
||||
|
||||
double l = hsl.lightness() + m_l;
|
||||
l = MID(0.0, l, 1.0);
|
||||
|
||||
hsl.hue(h);
|
||||
hsl.saturation(s);
|
||||
hsl.lightness(l);
|
||||
gfx::Rgb rgb(hsl);
|
||||
|
||||
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
||||
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
||||
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
||||
if (a && (target & TARGET_ALPHA_CHANNEL))
|
||||
a = MID(0, a+m_a, 255);
|
||||
|
||||
if (target & (TARGET_RED_CHANNEL |
|
||||
TARGET_GREEN_CHANNEL |
|
||||
TARGET_BLUE_CHANNEL |
|
||||
TARGET_ALPHA_CHANNEL))
|
||||
c = rgba(r, g, b, a);
|
||||
color_t c = pal->getEntry(*(src_address++));
|
||||
applyHslFilterToRgb(target, c);
|
||||
*(dst_address++) = rgbmap->mapColor(rgba_getr(c),
|
||||
rgba_getg(c),
|
||||
rgba_getb(c),
|
||||
rgba_geta(c));
|
||||
}
|
||||
|
||||
newPal->setEntry(i, c);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void HueSaturationFilter::applyHslFilterToRgb(
|
||||
const Target target, doc::color_t& c)
|
||||
{
|
||||
int r = rgba_getr(c);
|
||||
int g = rgba_getg(c);
|
||||
int b = rgba_getb(c);
|
||||
int a = rgba_geta(c);
|
||||
|
||||
gfx::Hsl hsl(gfx::Rgb(r, g, b));
|
||||
|
||||
double h = hsl.hue() + m_h;
|
||||
while (h < 0.0) h += 360.0;
|
||||
h = std::fmod(h, 360.0);
|
||||
|
||||
double s = hsl.saturation() + m_s;
|
||||
s = MID(0.0, s, 1.0);
|
||||
|
||||
double l = hsl.lightness() + m_l;
|
||||
l = MID(0.0, l, 1.0);
|
||||
|
||||
hsl.hue(h);
|
||||
hsl.saturation(s);
|
||||
hsl.lightness(l);
|
||||
gfx::Rgb rgb(hsl);
|
||||
|
||||
if (target & TARGET_RED_CHANNEL ) r = rgb.red();
|
||||
if (target & TARGET_GREEN_CHANNEL) g = rgb.green();
|
||||
if (target & TARGET_BLUE_CHANNEL ) b = rgb.blue();
|
||||
if (a && (target & TARGET_ALPHA_CHANNEL))
|
||||
a = MID(0, a+m_a, 255);
|
||||
|
||||
c = rgba(r, g, b, a);
|
||||
}
|
||||
|
||||
} // namespace filters
|
||||
|
@ -8,7 +8,9 @@
|
||||
#define FILTERS_HUE_SATURATION_FILTER_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "doc/color.h"
|
||||
#include "filters/filter.h"
|
||||
#include "filters/target.h"
|
||||
|
||||
namespace filters {
|
||||
|
||||
@ -28,6 +30,8 @@ namespace filters {
|
||||
void applyToIndexed(FilterManager* filterMgr);
|
||||
|
||||
private:
|
||||
void applyHslFilterToRgb(const Target target, doc::color_t& color);
|
||||
|
||||
double m_h, m_s, m_l;
|
||||
int m_a;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user