image helpers

This commit is contained in:
Fabien LOISON 2017-12-14 11:46:24 +01:00
parent b9a0fcd501
commit ac8f7c61b4
No known key found for this signature in database
GPG Key ID: FF90CA148348048E
9 changed files with 197 additions and 0 deletions

BIN
test/images/alpha.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

47
test/images/alpha.svg Normal file
View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
id="svg2"
height="128"
width="128">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0,-994.51962)"
id="layer1">
<rect
y="1028.5197"
x="50"
height="75"
width="75"
id="rect822"
style="opacity:1;fill:#3dcaca;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<circle
r="35.3125"
cy="1039.0197"
cx="39.875"
id="path820"
style="opacity:1;fill:#dc5f2b;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
id="path828"
d="m 43,1060.5196 -35,60 h 70 z"
style="fill:#9dca3d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
test/images/image1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
test/images/threshold.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

37
test/images/threshold.svg Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="128"
height="128"
id="svg2"
version="1.1">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<path
id="rect822"
d="M 0 0 L 0 128 L 128 128 L 128 0 L 0 0 z M 16 16 L 48 16 L 48 48 L 16 48 L 16 16 z "
style="opacity:1;fill:#3dcaca;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.9;fill:#abc837;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4489"
width="36"
height="36"
x="14.000004"
y="14" />
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="128"
height="128"
id="svg2"
version="1.1">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(0,-994.51962)">
<rect
y="994.51959"
x="0"
height="128"
width="128"
id="rect4486"
style="opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#3dcaca;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect822"
width="75"
height="75"
x="50"
y="1028.5197" />
<circle
style="opacity:1;fill:#dc5f2b;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path820"
cx="39.875"
cy="1039.0197"
r="35.3125" />
<path
style="fill:#9dca3d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 43,1060.5196 -35,60 h 70 z"
id="path828" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,40 @@
import pytest
from PIL import Image
from yoga.image import helpers
class TestImageHaveAlpha(object):
def test_jpeg_without_alpha(self):
image = Image.open("test/images/image1.jpg")
assert not helpers.image_have_alpha(image)
def test_png_without_alpha(self):
image = Image.open("test/images/unused-alpha.png")
assert not helpers.image_have_alpha(image)
def test_png_with_alpha(self):
image = Image.open("test/images/alpha.png")
assert helpers.image_have_alpha(image)
def test_threshold(self):
image = Image.open("test/images/threshold.png")
assert helpers.image_have_alpha(image, 0xEF)
assert not helpers.image_have_alpha(image, 0xE0)
class TestGessImageFormat(object):
def test_jpeg_image(self):
image_bytes = open("test/images/image1.jpg", "rb").read()
assert helpers.guess_image_format(image_bytes) == "jpeg"
def test_png_image(self):
image_bytes = open("test/images/alpha.png", "rb").read()
assert helpers.guess_image_format(image_bytes) == "png"
def test_unsuported_image_format(self):
image_bytes = open("test/images/alpha.svg", "rb").read()
with pytest.raises(ValueError):
helpers.guess_image_format(image_bytes)

19
yoga/image/helpers.py Normal file
View File

@ -0,0 +1,19 @@
def image_have_alpha(image, threshold=0xFE):
if threshold <= 0:
return False
if image.mode != "RGBA":
return False
alpha_band = image.getdata(band=3) # bands: R=0, G=1, B=2, A=3
for pix in alpha_band:
if pix <= threshold:
return True
return False
def guess_image_format(image_initial_bytes):
if image_initial_bytes.startswith(b"\xFF\xD8\xFF\xE0"):
return "jpeg"
elif image_initial_bytes.startswith(b"\x89PNG\r\n"):
return "png"
else:
raise ValueError("Unsupported image format")