-
Notifications
You must be signed in to change notification settings - Fork 1
/
gimp_generate_derivatives.py
executable file
·141 lines (127 loc) · 4.21 KB
/
gimp_generate_derivatives.py
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#! /usr/bin/env python
import json
import mimetypes
import os
import re
import gimp
from gimpfu import *
from lib import (
guess_extension,
guess_mimetype,
listfiles,
)
QUALITY_FACTOR = 0.90
LOSSY = QUALITY_FACTOR < 1
def save_webp(image, drawable, path, filename):
pdb.file_webp_save(
image,
drawable,
path,
filename,
0, # preset=default
0 if LOSSY else 1, # lossless
100 * QUALITY_FACTOR, # quality,
100, # alpha quality
0, # use layers for animation
0, # loop indefinitely
0, # minimum animation size
0, # max distance between keyframes
1, # save exif data
1, # save iptc data (whatever that is)
1, # same xmp data (whatever that is)
0, # delay to use when timestamps not available
0, # force delay on all frames
)
def save_png(image, drawable, path, filename):
pdb.file_png_save(
image,
drawable,
path,
filename,
0 if LOSSY else 1, # use adam7 interlacing
9 - int(9 * QUALITY_FACTOR), # deflate compression factor,
1, # write bKGD chunk
1, # write gAMA chunk
1, # write oFFs chunk
1, # write pHYs chunk
1, # write tIME chunk
)
def save_jpg(image, drawable, path, filename):
# See: https://en.wikibooks.org/wiki/GIMP/Saving_as_JPEG
pdb.file_jpeg_save(
image,
drawable,
path,
filename,
QUALITY_FACTOR, # quality
0.10, # smoothing (whatever that is)
1, # optimize
1, # progressive
'', # comment
1, # subsmp
0, # baseline
16, # restart (apparent default in Gimp UI)
0, # DCT
)
MIMETYPE_SAVE_FUNC_MAP = {
'image/webp': save_webp,
'image/png': save_png,
'image/jpeg': save_jpg,
}
def run(
src_dir,
input_filename_regex,
dest_dir,
output_filename_template,
mimetypes,
widths,
overwrite,
show_skipped
):
"""Generate derivatives as required by derekenos.com-generator
github.com/derekenos/derekenos.com-generator
"""
INPUT_FILENAME_REGEX = re.compile(input_filename_regex)
# Ensure that widths are sorted descending.
widths = sorted(widths, reverse=True)
for filename, file_path in listfiles(src_dir):
# Ignore non-image files.
if not guess_mimetype(filename).startswith('image/'):
continue
# Parse the required fields from the filename.
match_d = INPUT_FILENAME_REGEX.match(filename).groupdict()
item_name = match_d['item_name']
asset_id = match_d['asset_id']
orig_width = int(match_d['width'])
# Open the image.
image = pdb.gimp_file_load(file_path, filename)
# If any requested widths are larger than the original image,
# add the original width to the list and drop the larger values.
i = next(i for i, width in enumerate(widths) if width < image.width)
final_widths = [image.width] + widths[i:] if i > 0 else widths
for width in final_widths:
if image.width > width:
# Scale image down to width.
height = int(float(width) / image.width * image.height)
pdb.gimp_image_scale(image, width, height)
for mimetype in mimetypes:
out_fn = output_filename_template.format(
item_name=item_name,
asset_id=asset_id,
width=width,
extension=guess_extension(mimetype)
)
out_path = os.path.join(dest_dir, out_fn)
# Skip path if overwrite is False and file already exists.
if not overwrite and os.path.exists(out_path):
if show_skipped:
print('Skipping: {}'.format(out_path))
continue
# Invoke either a custom or default save function.
MIMETYPE_SAVE_FUNC_MAP.get(mimetype, pdb.gimp_file_save)(
image,
image.active_drawable,
out_path,
out_fn
)
print('Wrote: {}'.format(out_path))