add Overlay chop

This commit is contained in:
Dag Wästberg 2019-11-22 14:30:43 +01:00 committed by Andrew Murray
parent c8a46ef387
commit 13c1b7070d
6 changed files with 47 additions and 0 deletions

View File

@ -40,6 +40,7 @@ def test_sanity():
ImageChops.softlight(im, im) ImageChops.softlight(im, im)
ImageChops.hardlight(im, im) ImageChops.hardlight(im, im)
ImageChops.overlay(im, im)
ImageChops.offset(im, 10) ImageChops.offset(im, 10)
ImageChops.offset(im, 10, 20) ImageChops.offset(im, 10, 20)
@ -391,6 +392,19 @@ def test_hardlight(self):
self.assertEqual(new.getpixel((15, 100)), (1, 1, 2)) self.assertEqual(new.getpixel((15, 100)), (1, 1, 2))
def test_overlay(self):
# Arrange
im1 = Image.open("Tests/images/hopper.png")
im2 = Image.open("Tests/images/hopper-XYZ.png")
# Act
new = ImageChops.overlay(im1, im2)
# Assert
self.assertEqual(new.getpixel((64, 64)), (159, 50, 27))
self.assertEqual(new.getpixel((15, 100)), (1, 1, 2))
def test_logical(): def test_logical():
def table(op, a, b): def table(op, a, b):
out = [] out = []

View File

@ -38,6 +38,7 @@ operations in this module).
.. autofunction:: PIL.ImageChops.multiply .. autofunction:: PIL.ImageChops.multiply
.. autofunction:: PIL.ImageChops.softlight .. autofunction:: PIL.ImageChops.softlight
.. autofunction:: PIL.ImageChops.hardlight .. autofunction:: PIL.ImageChops.hardlight
.. autofunction:: PIL.ImageChops.overlay
.. py:method:: PIL.ImageChops.offset(image, xoffset, yoffset=None) .. py:method:: PIL.ImageChops.offset(image, xoffset, yoffset=None)
Returns a copy of the image where data has been offset by the given Returns a copy of the image where data has been offset by the given

View File

@ -160,6 +160,17 @@ def hardlight(image1, image2):
image2.load() image2.load()
return image1._new(image1.im.chop_hardlight(image2.im)) return image1._new(image1.im.chop_hardlight(image2.im))
def overlay(image1, image2):
"""
Superimposes two images on top of each other using the Overlay algorithm
:rtype: :py:class:`~PIL.Image.Image`
"""
image1.load()
image2.load()
return image1._new(image1.im.chop_overlay(image2.im))
def add(image1, image2, scale=1.0, offset=0): def add(image1, image2, scale=1.0, offset=0):
""" """
Adds two images, dividing the result by scale and adding the Adds two images, dividing the result by scale and adding the

View File

@ -2427,6 +2427,17 @@ _chop_hardlight(ImagingObject* self, PyObject* args)
return PyImagingNew(ImagingChopHardLight(self->image, imagep->image)); return PyImagingNew(ImagingChopHardLight(self->image, imagep->image));
} }
static PyObject*
_chop_overlay(ImagingObject* self, PyObject* args)
{
ImagingObject* imagep;
if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
return NULL;
return PyImagingNew(ImagingOverlay(self->image, imagep->image));
}
#endif #endif
@ -3348,6 +3359,7 @@ static struct PyMethodDef methods[] = {
{"chop_xor", (PyCFunction)_chop_xor, 1}, {"chop_xor", (PyCFunction)_chop_xor, 1},
{"chop_softlight", (PyCFunction)_chop_softlight, 1}, {"chop_softlight", (PyCFunction)_chop_softlight, 1},
{"chop_hardlight", (PyCFunction)_chop_hardlight, 1}, {"chop_hardlight", (PyCFunction)_chop_hardlight, 1},
{"chop_overlay", (PyCFunction)_chop_overlay, 1},
#endif #endif

View File

@ -164,3 +164,11 @@ ImagingChopHardLight(Imaging imIn1, Imaging imIn2)
: 255 - ( ((255-in2[x]) * (255-in1[x])) / 127) : 255 - ( ((255-in2[x]) * (255-in1[x])) / 127)
, NULL); , NULL);
} }
Imaging
ImagingOverlay(Imaging imIn1, Imaging imIn2)
{
CHOP2( (in1[x]<128) ? ( (in1[x]*in2[x])/127)
: 255 - ( ((255-in1[x]) * (255-in2[x])) / 127)
, NULL);
}

View File

@ -341,6 +341,7 @@ extern Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2);
extern Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2); extern Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2);
extern Imaging ImagingChopSoftLight(Imaging imIn1, Imaging imIn2); extern Imaging ImagingChopSoftLight(Imaging imIn1, Imaging imIn2);
extern Imaging ImagingChopHardLight(Imaging imIn1, Imaging imIn2); extern Imaging ImagingChopHardLight(Imaging imIn1, Imaging imIn2);
extern Imaging ImagingOverlay(Imaging imIn1, Imaging imIn2);
/* "1" images only */ /* "1" images only */
extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2); extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2);