diff options
Diffstat (limited to 'bsie/extractor')
-rw-r--r-- | bsie/extractor/base.py | 1 | ||||
-rw-r--r-- | bsie/extractor/image/colors_spatial.py | 2 | ||||
-rw-r--r-- | bsie/extractor/preview.py | 99 |
3 files changed, 101 insertions, 1 deletions
diff --git a/bsie/extractor/base.py b/bsie/extractor/base.py index 7401244..89183f9 100644 --- a/bsie/extractor/base.py +++ b/bsie/extractor/base.py @@ -30,6 +30,7 @@ SCHEMA_PREAMBLE = ''' # common bsfs prefixes prefix bsfs: <http://bsfs.ai/schema/> prefix bse: <http://bsfs.ai/schema/Entity#> + prefix bsp: <http://bsfs.ai/schema/Preview#> # default definitions bsfs:Array rdfs:subClassOf bsfs:Literal . diff --git a/bsie/extractor/image/colors_spatial.py b/bsie/extractor/image/colors_spatial.py index ce5b9f2..15fd281 100644 --- a/bsie/extractor/image/colors_spatial.py +++ b/bsie/extractor/image/colors_spatial.py @@ -120,7 +120,7 @@ class ColorsSpatial(base.Extractor): def extract( self, subject: node.Node, - content: PIL.Image, + content: PIL.Image.Image, principals: typing.Iterable[bsfs.schema.Predicate], ) -> typing.Iterator[typing.Tuple[node.Node, bsfs.schema.Predicate, typing.Any]]: # check principals diff --git a/bsie/extractor/preview.py b/bsie/extractor/preview.py new file mode 100644 index 0000000..1531d62 --- /dev/null +++ b/bsie/extractor/preview.py @@ -0,0 +1,99 @@ +""" + +Part of the bsie module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# imports +import io +import typing + +# external imports +import PIL.Image + +# bsie imports +from bsie.utils import bsfs, node, ns + +# inner-module imports +from . import base + +# exports +__all__: typing.Sequence[str] = ( + 'Preview', + ) + + +## code ## + +class Preview(base.Extractor): + """Extract previews.""" + + CONTENT_READER = 'bsie.reader.preview.Preview' + + def __init__(self, max_sides: typing.Iterable[int]): + super().__init__(bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' + + bsfs:Preview rdfs:subClassOf bsfs:Node . + bsfs:BinaryBlob rdfs:subClassOf bsfs:Literal . + bsfs:JPEG rdfs:subClassOf bsfs:BinaryBlob . + + bse:preview rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:File ; + rdfs:range bsfs:Preview ; + bsfs:unique "false"^^xsd:boolean . + + bsp:width rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Preview ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + + bsp:height rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Preview ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + + bsp:asset rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Preview ; + rdfs:range bsfs:JPEG ; + bsfs:unique "true"^^xsd:boolean . + + ''')) + # initialize extra args + self.max_sides = set(max_sides) + + def __eq__(self, other: typing.Any) -> bool: + return super().__eq__(other) \ + and self.max_sides == other.max_sides + + def __hash__(self) -> int: + return hash((super().__hash__(), tuple(sorted(self.max_sides)))) + + def extract( + self, + subject: node.Node, + content: typing.Callable[[int], PIL.Image.Image], + principals: typing.Iterable[bsfs.schema.Predicate], + ) -> typing.Iterator[typing.Tuple[node.Node, bsfs.schema.Predicate, typing.Any]]: + # check principals + if self.schema.predicate(ns.bse.preview) not in principals: + return + + for max_side in self.max_sides: + # get the preview in the right resolution + img = content(max_side) + # convert the preview to jpeg + buffer = io.BytesIO() + img.save(buffer, format='jpeg') + # create a preview node + preview = node.Node(ns.bsfs.Preview, + ucid=bsfs.uuid.UCID.from_bytes(buffer.getvalue()), + size=max_side, + source=subject, + ) + # yield triples + yield subject, self.schema.predicate(ns.bse.preview), preview + yield preview, self.schema.predicate(ns.bsp.width), img.width + yield preview, self.schema.predicate(ns.bsp.height), img.height + yield preview, self.schema.predicate(ns.bsp.asset), buffer.getvalue() + +## EOF ## |