-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderingContext.py
More file actions
74 lines (69 loc) · 2.87 KB
/
renderingContext.py
File metadata and controls
74 lines (69 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# -*- coding: utf-8 -*-
"""
Used to track an image render
"""
from typing import *
import PIL
from imageTools import *
from smartimage.errors import SmartimageError
class RenderingContext:
"""
Used to keep track of atributes while rendering an image from layers
and also a box to keep utility functions in.
"""
def __init__(self):
self.desired:Bounds=Bounds(0,0,0,0)
self.cur_rot:float=0
self.cur:Bounds=Bounds(0,0,0,0)
self.cur_image:Union[PIL.Image.Image,None]=None
self.visitedLayers:Set['Layer']=set()
def log(self,*vals)->NoReturn:
"""
write something to the rendering debug log
"""
print((' '*len(self.visitedLayers))+(' '.join([str(v) for v in vals])))
def renderImage(self,layer:'Layer')->Union[PIL.Image.Image,None]:
"""
render an image from the layer image and all of its children
WARNING: Do not modify the image without doing a .copy() first!
"""
image=None
# loop prevention
if layer.elementId in self.visitedLayers:
info=(layer.elementId,layer.name)
raise SmartimageError(layer,'Link loop with layer %s "%s"'%info)
self.visitedLayers.add(layer.elementId)
# push a new variable context
# do we need to do anything?
opacity=layer.opacity
if opacity<=0.0 or not layer.visible:
self.log('skipping',layer.name)
else:
self.log('creating new %s layer named "%s"'%(layer.__class__.__name__,layer.name))
image=layer.image # NOTE: base image can be None
for childLayer in layer.children:
childImage=childLayer.renderImage(self)
image=composite(childImage,image,
opacity=childLayer.opacity,blendMode=childLayer.blendMode,mask=childLayer.mask,
position=childLayer.location,resize=True)
self.log('adding child layer "%s" at %s'%(childLayer.name,childLayer.location))
if layer.cropping is not None:
image=image.crop(layer.cropping)
if layer.rotation%360!=0:
self.log('rotating',layer.name)
bounds=Bounds(0,0,image.width,image.height)
bounds.rotateFit(layer.rotation)
image=extendImageCanvas(image,bounds)
image=image.rotate(layer.rotation)
# logging
if image is None:
self.log('info','for "%s":'%layer.name)
self.log('info',' NULL IMAGE')
else:
self.log('info','for "%s":'%layer.name)
self.log('info',' mode='+image.mode)
self.log('info',' bounds=(0,0,%d,%d)'%(image.width,image.height))
self.log('finished',layer.name)
# pop off tracking info for this layer
self.visitedLayers.pop()
return image