Add overlay and multiply effects to gdImageSetPixel
parent
4b86e06937
commit
b39f92b195
67
src/gd.c
67
src/gd.c
|
@ -1061,10 +1061,20 @@ BGD_DECLARE(void) gdImageSetPixel (gdImagePtr im, int x, int y, int color)
|
|||
default:
|
||||
if (gdImageBoundsSafeMacro (im, x, y)) {
|
||||
if (im->trueColor) {
|
||||
if (im->alphaBlendingFlag) {
|
||||
im->tpixels[y][x] = gdAlphaBlend (im->tpixels[y][x], color);
|
||||
} else {
|
||||
im->tpixels[y][x] = color;
|
||||
switch (im->alphaBlendingFlag) {
|
||||
default:
|
||||
case gdEffectReplace:
|
||||
im->tpixels[y][x] = color;
|
||||
break;
|
||||
case gdEffectNormal:
|
||||
im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
|
||||
break;
|
||||
case gdEffectOverlay :
|
||||
im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);
|
||||
break;
|
||||
case gdEffectMultiply :
|
||||
im->tpixels[y][x] = gdLayerMultiply(im->tpixels[y][x], color);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
im->pixels[y][x] = color;
|
||||
|
@ -3330,6 +3340,55 @@ BGD_DECLARE(int) gdAlphaBlend (int dst, int src)
|
|||
return ((alpha << 24) + (red << 16) + (green << 8) + blue);
|
||||
}
|
||||
|
||||
static int gdAlphaOverlayColor (int src, int dst, int max );
|
||||
BGD_DECLARE(int) gdLayerOverlay (int dst, int src)
|
||||
{
|
||||
int a1, a2;
|
||||
a1 = gdAlphaMax - gdTrueColorGetAlpha(dst);
|
||||
a2 = gdAlphaMax - gdTrueColorGetAlpha(src);
|
||||
return ( ((gdAlphaMax - a1*a2/gdAlphaMax) << 24) +
|
||||
(gdAlphaOverlayColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), gdRedMax ) << 16) +
|
||||
(gdAlphaOverlayColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), gdGreenMax ) << 8) +
|
||||
(gdAlphaOverlayColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), gdBlueMax ))
|
||||
);
|
||||
}
|
||||
|
||||
/* Apply 'overlay' effect - background pixels are colourised by the foreground colour */
|
||||
static int gdAlphaOverlayColor (int src, int dst, int max )
|
||||
{
|
||||
dst = dst << 1;
|
||||
if( dst > max ) {
|
||||
/* in the "light" zone */
|
||||
return dst + (src << 1) - (dst * src / max) - max;
|
||||
} else {
|
||||
/* in the "dark" zone */
|
||||
return dst * src / max;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply 'multiply' effect */
|
||||
BGD_DECLARE(int) gdLayerMultiply (int dst, int src)
|
||||
{
|
||||
int a1, a2, r1, r2, g1, g2, b1, b2;
|
||||
a1 = gdAlphaMax - gdTrueColorGetAlpha(src);
|
||||
a2 = gdAlphaMax - gdTrueColorGetAlpha(dst);
|
||||
|
||||
r1 = gdRedMax - (a1 * (gdRedMax - gdTrueColorGetRed(src))) / gdAlphaMax;
|
||||
r2 = gdRedMax - (a2 * (gdRedMax - gdTrueColorGetRed(dst))) / gdAlphaMax;
|
||||
g1 = gdGreenMax - (a1 * (gdGreenMax - gdTrueColorGetGreen(src))) / gdAlphaMax;
|
||||
g2 = gdGreenMax - (a2 * (gdGreenMax - gdTrueColorGetGreen(dst))) / gdAlphaMax;
|
||||
b1 = gdBlueMax - (a1 * (gdBlueMax - gdTrueColorGetBlue(src))) / gdAlphaMax;
|
||||
b2 = gdBlueMax - (a2 * (gdBlueMax - gdTrueColorGetBlue(dst))) / gdAlphaMax ;
|
||||
|
||||
a1 = gdAlphaMax - a1;
|
||||
a2 = gdAlphaMax - a2;
|
||||
return ( ((a1*a2/gdAlphaMax) << 24) +
|
||||
((r1*r2/gdRedMax) << 16) +
|
||||
((g1*g2/gdGreenMax) << 8) +
|
||||
((b1*b2/gdBlueMax))
|
||||
);
|
||||
}
|
||||
|
||||
BGD_DECLARE(void) gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg)
|
||||
{
|
||||
im->alphaBlendingFlag = alphaBlendingArg;
|
||||
|
|
9
src/gd.h
9
src/gd.h
|
@ -139,6 +139,7 @@ extern "C" {
|
|||
#define gdEffectAlphaBlend 1
|
||||
#define gdEffectNormal 2
|
||||
#define gdEffectOverlay 3
|
||||
#define gdEffectMultiply 4
|
||||
|
||||
#define GD_TRUE 1
|
||||
#define GD_FALSE 0
|
||||
|
@ -154,7 +155,9 @@ extern "C" {
|
|||
The resulting color is opaque. */
|
||||
|
||||
BGD_DECLARE(int) gdAlphaBlend (int dest, int src);
|
||||
|
||||
BGD_DECLARE(int) gdLayerOverlay (int dest, int src);
|
||||
BGD_DECLARE(int) gdLayerMultiply (int dest, int src);
|
||||
|
||||
enum gdPaletteQuantizationMethod {
|
||||
GD_QUANT_DEFAULT = 0,
|
||||
GD_QUANT_JQUANT = 1, /* libjpeg's old median cut. Fast, but only uses 16-bit color. */
|
||||
|
@ -565,7 +568,9 @@ BGD_DECLARE(void) gdImageDestroy (gdImagePtr im);
|
|||
alpha channel value of 'color'; default is to overwrite.
|
||||
Tiling and line styling are also implemented
|
||||
here. All other gd drawing functions pass through this call,
|
||||
allowing for many useful effects. */
|
||||
allowing for many useful effects.
|
||||
Overlay and multiply effects are used when gdImageAlphaBlending
|
||||
is passed gdEffectOverlay and gdEffectMultiply */
|
||||
|
||||
BGD_DECLARE(void) gdImageSetPixel (gdImagePtr im, int x, int y, int color);
|
||||
/* FreeType 2 text output with hook to extra flags */
|
||||
|
|
Loading…
Reference in New Issue