Skip to content

Commit 3b02bd5

Browse files
marojenkacodingjoe
authored andcommitted
Add process_variation classmethod to simplify customization (#188)
* Add missed variables to logger * make rendervariation easier to customize * a bit ugly way to make management command aware that if might be working with children of StdImageFieldFile
1 parent 3d98e33 commit 3b02bd5

File tree

3 files changed

+58
-48
lines changed

3 files changed

+58
-48
lines changed

stdimage/management/commands/rendervariations.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def render(field, images, count, replace, do_render):
5959
variations=field.variations,
6060
replace=replace,
6161
storage=field.storage.deconstruct()[0],
62+
field_class=field.attr_class,
6263
)
6364
for file_name in images
6465
)
@@ -78,6 +79,7 @@ def render_field_variations(kwargs):
7879
kwargs['storage'] = get_storage_class(kwargs['storage'])()
7980
do_render = kwargs.pop('do_render')
8081
if callable(do_render):
82+
kwargs.pop('field_class')
8183
do_render = do_render(**kwargs)
8284
if do_render:
8385
render_variations(**kwargs)

stdimage/models.py

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -62,63 +62,71 @@ def render_variation(cls, file_name, variation, replace=False,
6262
if storage.exists(variation_name):
6363
if replace:
6464
storage.delete(variation_name)
65-
logger.info('File "{}" already exists and has been replaced.')
65+
logger.info('File "{}" already exists and has been replaced.',
66+
variation_name)
6667
else:
67-
logger.info('File "{}" already exists.')
68+
logger.info('File "{}" already exists.', variation_name)
6869
return variation_name
6970

70-
resample = variation['resample']
71-
7271
ImageFile.LOAD_TRUNCATED_IMAGES = True
7372
with storage.open(file_name) as f:
7473
with Image.open(f) as img:
75-
save_kargs = {}
76-
file_format = img.format
77-
78-
if cls.is_smaller(img, variation):
79-
factor = 1
80-
while img.size[0] / factor \
81-
> 2 * variation['width'] \
82-
and img.size[1] * 2 / factor \
83-
> 2 * variation['height']:
84-
factor *= 2
85-
if factor > 1:
86-
img.thumbnail(
87-
(int(img.size[0] / factor),
88-
int(img.size[1] / factor)),
89-
resample=resample
90-
)
91-
92-
size = variation['width'], variation['height']
93-
size = tuple(int(i) if i != float('inf') else i
94-
for i in size)
95-
96-
if file_format == 'JPEG':
97-
# http://stackoverflow.com/a/21669827
98-
img = img.convert('RGB')
99-
save_kargs['optimize'] = True
100-
save_kargs['quality'] = 'web_high'
101-
if size[0] * size[1] > 10000: # roughly <10kb
102-
save_kargs['progressive'] = True
103-
104-
if variation['crop']:
105-
img = ImageOps.fit(
106-
img,
107-
size,
108-
method=resample
109-
)
110-
else:
111-
img.thumbnail(
112-
size,
113-
resample=resample
114-
)
115-
74+
img, save_kargs = cls.process_variation(variation, image=img)
11675
with BytesIO() as file_buffer:
117-
img.save(file_buffer, file_format, **save_kargs)
76+
img.save(file_buffer, **save_kargs)
11877
f = ContentFile(file_buffer.getvalue())
11978
storage.save(variation_name, f)
12079
return variation_name
12180

81+
@classmethod
82+
def process_variation(cls, variation, image):
83+
"""Process variation before actual saving."""
84+
save_kargs = {}
85+
file_format = image.format
86+
save_kargs['format'] = file_format
87+
88+
resample = variation['resample']
89+
90+
if cls.is_smaller(image, variation):
91+
factor = 1
92+
while image.size[0] / factor \
93+
> 2 * variation['width'] \
94+
and image.size[1] * 2 / factor \
95+
> 2 * variation['height']:
96+
factor *= 2
97+
if factor > 1:
98+
image.thumbnail(
99+
(int(image.size[0] / factor),
100+
int(image.size[1] / factor)),
101+
resample=resample
102+
)
103+
104+
size = variation['width'], variation['height']
105+
size = tuple(int(i) if i != float('inf') else i
106+
for i in size)
107+
108+
if file_format == 'JPEG':
109+
# http://stackoverflow.com/a/21669827
110+
image = image.convert('RGB')
111+
save_kargs['optimize'] = True
112+
save_kargs['quality'] = 'web_high'
113+
if size[0] * size[1] > 10000: # roughly <10kb
114+
save_kargs['progressive'] = True
115+
116+
if variation['crop']:
117+
image = ImageOps.fit(
118+
image,
119+
size,
120+
method=resample
121+
)
122+
else:
123+
image.thumbnail(
124+
size,
125+
resample=resample
126+
)
127+
128+
return image, save_kargs
129+
122130
@classmethod
123131
def get_variation_name(cls, file_name, variation_name):
124132
"""Return the variation file name based on the variation."""

stdimage/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ def pre_save_delete_callback(sender, instance, **kwargs):
8686

8787

8888
def render_variations(file_name, variations, replace=False,
89-
storage=default_storage):
89+
storage=default_storage, field_class=StdImageFieldFile):
9090
"""Render all variations for a given field."""
9191
for key, variation in variations.items():
92-
StdImageFieldFile.render_variation(
92+
field_class.render_variation(
9393
file_name, variation, replace, storage
9494
)

0 commit comments

Comments
 (0)