Merge pull request #384 from Elvish-Hunter/master
New ImagePathWML functions: ~SEPIA() and ~NEG()
This commit is contained in:
commit
a699094251
4 changed files with 119 additions and 0 deletions
|
@ -200,6 +200,16 @@ surface gs_modification::operator()(const surface& src) const
|
|||
return greyscale_image(src);
|
||||
}
|
||||
|
||||
surface sepia_modification::operator()(const surface &src) const
|
||||
{
|
||||
return sepia_image(src);
|
||||
}
|
||||
|
||||
surface negative_modification::operator()(const surface &src) const
|
||||
{
|
||||
return negative_image(src);
|
||||
}
|
||||
|
||||
surface plot_alpha_modification::operator()(const surface& src) const
|
||||
{
|
||||
return alpha_to_greyscale(src);
|
||||
|
@ -744,6 +754,18 @@ REGISTER_MOD_PARSER(GS, )
|
|||
return new gs_modification;
|
||||
}
|
||||
|
||||
// Sepia
|
||||
REGISTER_MOD_PARSER(SEPIA, )
|
||||
{
|
||||
return new sepia_modification;
|
||||
}
|
||||
|
||||
// Negative
|
||||
REGISTER_MOD_PARSER(NEG, )
|
||||
{
|
||||
return new negative_modification;
|
||||
}
|
||||
|
||||
// Plot Alpha
|
||||
REGISTER_MOD_PARSER(PLOT_ALPHA, )
|
||||
{
|
||||
|
|
|
@ -221,6 +221,22 @@ public:
|
|||
virtual surface operator()(const surface& src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Give to the image a sepia tint (SEPIA)
|
||||
*/
|
||||
struct sepia_modification : modification
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an image negative (NEG)
|
||||
*/
|
||||
struct negative_modification : modification
|
||||
{
|
||||
virtual surface operator()(const surface &src) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Plot Alpha (Alpha) modification
|
||||
*/
|
||||
|
|
|
@ -989,6 +989,85 @@ surface greyscale_image(const surface &surf, bool optimize)
|
|||
return optimize ? create_optimized_surface(nsurf) : nsurf;
|
||||
}
|
||||
|
||||
surface sepia_image(const surface &surf, bool optimize)
|
||||
{
|
||||
if(surf == NULL)
|
||||
return NULL;
|
||||
|
||||
surface nsurf(make_neutral_surface(surf));
|
||||
if(nsurf == NULL) {
|
||||
std::cerr << "failed to make neutral surface\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
surface_lock lock(nsurf);
|
||||
Uint32* beg = lock.pixels();
|
||||
Uint32* end = beg + nsurf->w*surf->h;
|
||||
|
||||
while(beg != end) {
|
||||
Uint8 alpha = (*beg) >> 24;
|
||||
|
||||
if(alpha) {
|
||||
Uint8 r, g, b;
|
||||
r = (*beg) >> 16;
|
||||
g = (*beg) >> 8;
|
||||
b = (*beg);
|
||||
|
||||
// this is the formula for applying a sepia effect
|
||||
// that can be found on various web sites
|
||||
// for example here: https://software.intel.com/sites/default/files/article/346220/sepiafilter-intelcilkplus.pdf
|
||||
Uint8 outRed = std::min(255, static_cast<int>((r * 0.393) + (g * 0.769) + (b * 0.189)));
|
||||
Uint8 outGreen = std::min(255, static_cast<int>((r * 0.349) + (g * 0.686) + (b * 0.168)));
|
||||
Uint8 outBlue = std::min(255, static_cast<int>((r * 0.272) + (g * 0.534) + (b * 0.131)));
|
||||
|
||||
*beg = (alpha << 24) | (outRed << 16) | (outGreen << 8) | (outBlue);
|
||||
}
|
||||
|
||||
++beg;
|
||||
}
|
||||
}
|
||||
|
||||
return optimize ? create_optimized_surface(nsurf) : nsurf;
|
||||
}
|
||||
|
||||
surface negative_image(const surface &surf, bool optimize)
|
||||
{
|
||||
if(surf == NULL)
|
||||
return NULL;
|
||||
|
||||
surface nsurf(make_neutral_surface(surf));
|
||||
if(nsurf == NULL) {
|
||||
std::cerr << "failed to make neutral surface\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
surface_lock lock(nsurf);
|
||||
Uint32* beg = lock.pixels();
|
||||
Uint32* end = beg + nsurf->w*surf->h;
|
||||
|
||||
while(beg != end) {
|
||||
Uint8 alpha = (*beg) >> 24;
|
||||
|
||||
if(alpha) {
|
||||
Uint8 r, g, b;
|
||||
r = (*beg) >> 16;
|
||||
g = (*beg) >> 8;
|
||||
b = (*beg);
|
||||
|
||||
// basically, to get a channel's negative it's enough
|
||||
// to subtract its value from 255
|
||||
*beg = (alpha << 24) | ((255 - r) << 16) | ((255 - g) << 8) | (255 - b);
|
||||
}
|
||||
|
||||
++beg;
|
||||
}
|
||||
}
|
||||
|
||||
return optimize ? create_optimized_surface(nsurf) : nsurf;
|
||||
}
|
||||
|
||||
surface alpha_to_greyscale(const surface &surf, bool optimize)
|
||||
{
|
||||
if(surf == NULL)
|
||||
|
|
|
@ -246,6 +246,8 @@ surface tile_surface(const surface &surf, int w, int h, bool optimize=true);
|
|||
|
||||
surface adjust_surface_color(const surface &surf, int r, int g, int b, bool optimize=true);
|
||||
surface greyscale_image(const surface &surf, bool optimize=true);
|
||||
surface sepia_image(const surface &surf, bool optimize=true);
|
||||
surface negative_image(const surface &surf, bool optimize=true);
|
||||
surface alpha_to_greyscale(const surface & surf, bool optimize=true);
|
||||
surface wipe_alpha(const surface & surf, bool optimize=true);
|
||||
/** create an heavy shadow of the image, by blurring, increasing alpha and darkening */
|
||||
|
|
Loading…
Add table
Reference in a new issue