Release: 8ad0730237b133d3d03c875bf7f97bba

This commit is contained in:
Dirk Alders 2020-02-03 00:03:58 +01:00
parent aa39140bc8
commit 1c06aab615
6 changed files with 4193 additions and 3091 deletions

View File

@ -24,8 +24,9 @@ media (Media Tools)
""" """
__DEPENDENCIES__ = [] __DEPENDENCIES__ = []
import io
import logging import logging
from PIL import Image, ImageEnhance from PIL import Image, ImageEnhance, ExifTags
logger_name = 'MEDIA' logger_name = 'MEDIA'
logger = logging.getLogger(logger_name) logger = logging.getLogger(logger_name)
@ -106,6 +107,13 @@ class image(object):
self._im = get_pil_image(media_instance) self._im = get_pil_image(media_instance)
if self._im is None: if self._im is None:
return False return False
try:
self._exif = dict(self._im._getexif().items())
except AttributeError:
self._exif = {}
if type(self._im) is not Image.Image:
self._im = self._im.copy()
logger.debug('loading image from %s', repr(media_instance))
return True return True
def save(self, full_path): def save(self, full_path):
@ -119,6 +127,12 @@ class image(object):
im.save(fh, 'JPEG') im.save(fh, 'JPEG')
return True return True
def image_data(self):
im = self._im.copy().convert('RGB')
output = io.BytesIO()
im.save(output, format='JPEG')
return output.getvalue()
def resize(self, max_size): def resize(self, max_size):
if self._im is None: if self._im is None:
logger.warning('No image available to be resized') logger.warning('No image available to be resized')
@ -130,11 +144,19 @@ class image(object):
self._im = self._im.resize((int(x * float(max_size) / xy_max), int(y * float(max_size) / xy_max)), Image.NEAREST).rotate(0) self._im = self._im.resize((int(x * float(max_size) / xy_max), int(y * float(max_size) / xy_max)), Image.NEAREST).rotate(0)
return True return True
def rotate_by_orientation(self, orientation): def rotate_by_orientation(self, orientation=None):
if self._im is None: if self._im is None:
logger.warning('No image available, rotation not possible') logger.warning('No image available, rotation not possible')
return False return False
if orientation is None:
exif_tags = dict((v, k) for k, v in ExifTags.TAGS.items())
try:
orientation = self._exif[exif_tags['Orientation']]
logger.debug("No orientation given, orientation %s extract from exif data", repr(orientation))
except KeyError:
return False
if orientation == ORIENTATION_HALF_ROTATED: if orientation == ORIENTATION_HALF_ROTATED:
angle = 180 angle = 180
elif orientation == ORIENTATION_LEFT_ROTATED: elif orientation == ORIENTATION_LEFT_ROTATED:

View File

@ -1,23 +1,23 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<coverage branch-rate="0.9643" branches-covered="81" branches-valid="84" complexity="0" line-rate="0.9759" lines-covered="324" lines-valid="332" timestamp="1580584174451" version="4.5"> <coverage branch-rate="0.9667" branches-covered="87" branches-valid="90" complexity="0" line-rate="0.9775" lines-covered="347" lines-valid="355" timestamp="1580683820455" version="4.5">
<!-- Generated by coverage.py: https://coverage.readthedocs.io --> <!-- Generated by coverage.py: https://coverage.readthedocs.io -->
<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
<sources/> <sources/>
<packages> <packages>
<package branch-rate="0.9643" complexity="0" line-rate="0.9759" name=".user_data.data.dirk.prj.unittest.media.pylibs.media"> <package branch-rate="0.9667" complexity="0" line-rate="0.9775" name=".user_data.data.dirk.prj.unittest.media.pylibs.media">
<classes> <classes>
<class branch-rate="0.9737" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/__init__.py" line-rate="0.9924" name="__init__.py"> <class branch-rate="0.9773" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/__init__.py" line-rate="0.9934" name="__init__.py">
<methods/> <methods/>
<lines> <lines>
<line hits="1" number="4"/> <line hits="1" number="4"/>
<line hits="1" number="25"/> <line hits="1" number="25"/>
<line hits="1" number="27"/> <line hits="1" number="27"/>
<line hits="1" number="28"/> <line hits="1" number="28"/>
<line hits="1" number="30"/> <line hits="1" number="29"/>
<line hits="1" number="31"/> <line hits="1" number="31"/>
<line hits="1" number="34"/> <line hits="1" number="32"/>
<line hits="1" number="37"/> <line hits="1" number="35"/>
<line hits="1" number="41"/> <line hits="1" number="38"/>
<line hits="1" number="42"/> <line hits="1" number="42"/>
<line hits="1" number="43"/> <line hits="1" number="43"/>
<line hits="1" number="44"/> <line hits="1" number="44"/>
@ -40,106 +40,126 @@
<line hits="1" number="61"/> <line hits="1" number="61"/>
<line hits="1" number="62"/> <line hits="1" number="62"/>
<line hits="1" number="63"/> <line hits="1" number="63"/>
<line hits="1" number="66"/> <line hits="1" number="64"/>
<line hits="1" number="67"/> <line hits="1" number="67"/>
<line hits="1" number="68"/> <line hits="1" number="68"/>
<line hits="1" number="70"/> <line hits="1" number="69"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="72"/> <line hits="1" number="71"/>
<line hits="1" number="73"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="73"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="74"/> <line hits="1" number="74"/>
<line hits="1" number="75"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="75"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="76"/> <line hits="1" number="76"/>
<line hits="1" number="77"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="77"/>
<line hits="1" number="79"/> <line hits="1" number="78"/>
<line hits="1" number="82"/> <line hits="1" number="80"/>
<line hits="1" number="83"/> <line hits="1" number="83"/>
<line hits="1" number="84"/> <line hits="1" number="84"/>
<line hits="1" number="85"/> <line hits="1" number="85"/>
<line hits="1" number="86"/> <line hits="1" number="86"/>
<line hits="1" number="87"/> <line hits="1" number="87"/>
<line hits="1" number="89"/> <line hits="1" number="88"/>
<line hits="1" number="90"/> <line hits="1" number="90"/>
<line hits="1" number="91"/> <line hits="1" number="91"/>
<line hits="1" number="92"/> <line hits="1" number="92"/>
<line hits="1" number="93"/> <line hits="1" number="93"/>
<line hits="1" number="96"/> <line hits="1" number="94"/>
<line hits="1" number="97"/> <line hits="1" number="97"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="98"/> <line hits="1" number="98"/>
<line hits="1" number="99"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="99"/>
<line hits="1" number="101"/> <line hits="1" number="100"/>
<line hits="1" number="103"/> <line hits="1" number="102"/>
<line hits="1" number="104"/> <line hits="1" number="104"/>
<line hits="1" number="106"/> <line hits="1" number="105"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="107"/> <line hits="1" number="107"/>
<line hits="1" number="108"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="108"/>
<line hits="1" number="109"/> <line hits="1" number="109"/>
<line hits="1" number="110"/>
<line hits="1" number="111"/> <line hits="1" number="111"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="112"/> <line hits="1" number="112"/>
<line hits="1" number="113"/> <line hits="1" number="113"/>
<line hits="1" number="114"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="114"/>
<line hits="1" number="115"/>
<line hits="1" number="116"/> <line hits="1" number="116"/>
<line hits="1" number="117"/> <line hits="1" number="117"/>
<line hits="1" number="118"/>
<line hits="1" number="119"/> <line hits="1" number="119"/>
<line hits="1" number="120"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="120"/>
<line hits="1" number="121"/>
<line hits="1" number="122"/> <line hits="1" number="122"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="123"/>
<line hits="1" number="124"/> <line hits="1" number="124"/>
<line hits="1" number="125"/> <line hits="1" number="125"/>
<line hits="1" number="126"/>
<line hits="1" number="127"/> <line hits="1" number="127"/>
<line hits="1" number="128"/> <line hits="1" number="128"/>
<line hits="1" number="129"/>
<line hits="1" number="130"/> <line hits="1" number="130"/>
<line hits="1" number="131"/> <line hits="1" number="131"/>
<line hits="1" number="132"/>
<line hits="1" number="133"/> <line hits="1" number="133"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="134"/> <line hits="1" number="134"/>
<line hits="1" number="135"/>
<line hits="1" number="136"/> <line hits="1" number="136"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="138"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="137"/>
<line hits="1" number="138"/>
<line hits="1" number="139"/> <line hits="1" number="139"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="140"/>
<line hits="1" number="141"/> <line hits="1" number="141"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="142"/> <line hits="1" number="142"/>
<line hits="1" number="143"/> <line hits="1" number="143"/>
<line hits="1" number="144"/>
<line hits="1" number="145"/> <line hits="1" number="145"/>
<line hits="1" number="146"/>
<line hits="1" number="147"/> <line hits="1" number="147"/>
<line hits="1" number="148"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="148"/>
<line hits="1" number="149"/> <line hits="1" number="149"/>
<line hits="1" number="151"/> <line hits="1" number="150"/>
<line hits="1" number="152"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="152"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="153"/>
<line hits="1" number="154"/> <line hits="1" number="154"/>
<line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="158" number="155"/> <line hits="1" number="155"/>
<line hits="1" number="156"/> <line hits="1" number="156"/>
<line hits="0" number="158"/> <line hits="1" number="157"/>
<line hits="1" number="158"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="160"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="160"/>
<line hits="1" number="161"/> <line hits="1" number="161"/>
<line hits="1" number="162"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="162"/>
<line hits="1" number="163"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="164"/>
<line hits="1" number="165"/> <line hits="1" number="165"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="166"/>
<line hits="1" number="167"/> <line hits="1" number="167"/>
<line hits="1" number="168"/> <line hits="1" number="168"/>
<line hits="1" number="169"/>
<line hits="1" number="170"/> <line hits="1" number="170"/>
<line hits="1" number="172"/> <line hits="1" number="171"/>
<line hits="1" number="173"/> <line hits="1" number="173"/>
<line hits="1" number="174"/> <line hits="1" number="174"/>
<line hits="1" number="176"/> <line hits="1" number="176"/>
<line hits="1" number="179"/> <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="180" number="177"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="181"/> <line hits="1" number="178"/>
<line hits="1" number="182"/> <line hits="0" number="180"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="183"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="182"/>
<line hits="1" number="183"/>
<line hits="1" number="184"/> <line hits="1" number="184"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="185"/> <line hits="1" number="187"/>
<line hits="1" number="186"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="188"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="187"/> <line hits="1" number="189"/>
<line hits="1" number="188"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="189"/>
<line hits="1" number="190"/> <line hits="1" number="190"/>
<line hits="1" number="192"/> <line hits="1" number="192"/>
<line hits="1" number="193"/> <line hits="1" number="194"/>
<line hits="1" number="195"/> <line hits="1" number="195"/>
<line hits="1" number="196"/> <line hits="1" number="196"/>
<line hits="1" number="198"/> <line hits="1" number="198"/>
<line hits="1" number="201"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="203"/>
<line hits="1" number="204"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="205"/>
<line hits="1" number="206"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="207"/>
<line hits="1" number="208"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="209"/>
<line hits="1" number="210"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="211"/>
<line hits="1" number="212"/>
<line hits="1" number="214"/>
<line hits="1" number="215"/>
<line hits="1" number="217"/>
<line hits="1" number="218"/>
<line hits="1" number="220"/>
</lines> </lines>
</class> </class>
<class branch-rate="1" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/common.py" line-rate="1" name="common.py"> <class branch-rate="1" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/common.py" line-rate="1" name="common.py">
@ -197,7 +217,7 @@
<line hits="1" number="35"/> <line hits="1" number="35"/>
</lines> </lines>
</class> </class>
<class branch-rate="0.9667" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/metadata.py" line-rate="0.9808" name="metadata.py"> <class branch-rate="0.9667" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/metadata.py" line-rate="0.9811" name="metadata.py">
<methods/> <methods/>
<lines> <lines>
<line hits="1" number="1"/> <line hits="1" number="1"/>
@ -334,28 +354,31 @@
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="194"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="194"/>
<line hits="1" number="195"/> <line hits="1" number="195"/>
<line hits="1" number="196"/> <line hits="1" number="196"/>
<line hits="1" number="197"/>
<line hits="1" number="198"/>
<line hits="1" number="199"/> <line hits="1" number="199"/>
<line hits="1" number="200"/> <line hits="1" number="202"/>
<line hits="1" number="201"/> <line hits="1" number="203"/>
<line hits="1" number="204"/> <line hits="1" number="204"/>
<line hits="1" number="205"/>
<line hits="1" number="206"/>
<line hits="1" number="207"/> <line hits="1" number="207"/>
<line branch="true" condition-coverage="100% (2/2)" hits="1" number="208"/> <line hits="1" number="208"/>
<line hits="1" number="209"/> <line hits="1" number="209"/>
<line hits="1" number="210"/> <line hits="1" number="210"/>
<line hits="1" number="211"/> <line branch="true" condition-coverage="100% (2/2)" hits="1" number="211"/>
<line hits="1" number="212"/> <line hits="1" number="212"/>
<line hits="1" number="213"/> <line hits="1" number="213"/>
<line hits="1" number="214"/> <line hits="1" number="214"/>
<line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="215"/> <line hits="1" number="215"/>
<line hits="1" number="216"/> <line hits="1" number="216"/>
<line hits="1" number="217"/> <line hits="1" number="217"/>
<line hits="1" number="218"/> <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="218"/>
<line hits="1" number="219"/>
<line hits="1" number="220"/>
<line hits="1" number="221"/> <line hits="1" number="221"/>
<line hits="1" number="222"/>
<line hits="1" number="223"/>
<line hits="1" number="224"/> <line hits="1" number="224"/>
<line hits="1" number="225"/>
<line hits="1" number="226"/>
<line hits="1" number="227"/>
</lines> </lines>
</class> </class>
</classes> </classes>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -14,7 +14,7 @@ def get_pil_image(media_instance):
if type(media_instance) == str: if type(media_instance) == str:
ft = common.get_filetype(media_instance) ft = common.get_filetype(media_instance)
if ft == common.FILETYPE_IMAGE: if ft == common.FILETYPE_IMAGE:
return Image.open(media_instance).copy() return Image.open(media_instance)
elif ft == common.FILETYPE_VIDEO: elif ft == common.FILETYPE_VIDEO:
if platform.system() == 'Linux': if platform.system() == 'Linux':
cmd = 'ffmpeg -ss 0.5 -i "' + media_instance + '" -vframes 1 -f image2pipe pipe:1 2> /dev/null' cmd = 'ffmpeg -ss 0.5 -i "' + media_instance + '" -vframes 1 -f image2pipe pipe:1 2> /dev/null'

View File

@ -193,7 +193,10 @@ def __int_conv__(value):
p = value.find(c) p = value.find(c)
if p >= 0: if p >= 0:
value = value[:p] value = value[:p]
return int(value) try:
return int(value)
except ValueError:
return None
def __num_denum_conv__(data): def __num_denum_conv__(data):