Skip to content

Commit 83507ec

Browse files
committed
Refactor images-resize to use content-task
This refactor will avoid re-modifying unchanged image files between builds, and also pave the way for the manifest task
1 parent 49177f4 commit 83507ec

2 files changed

Lines changed: 90 additions & 53 deletions

File tree

src/io/perun.clj

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -130,32 +130,6 @@
130130
(io.perun.contrib.images-dimensions/images-dimensions ~metas {}))]
131131
(pm/set-meta fileset updated-metas))))
132132

133-
(def ^:private ^:deps images-resize-deps
134-
'[[image-resizer "0.1.8"]])
135-
136-
(def ^:private +images-resize-defaults+
137-
{:out-dir "public"
138-
:resolutions #{3840 2560 1920 1280 1024 640}})
139-
140-
(deftask images-resize
141-
"Resize images to the provided resolutions.
142-
Each image file would have resolution appended to it's name:
143-
e.x. san-francisco.jpg would become san-francisco_3840.jpg"
144-
[o out-dir OUTDIR str "the output directory"
145-
r resolutions RESOLUTIONS #{int} "resoulitions to which images should be resized"]
146-
(boot/with-pre-wrap fileset
147-
(let [options (merge +images-resize-defaults+ *opts*)
148-
tmp (boot/tmp-dir!)
149-
pod (create-pod images-resize-deps)
150-
metas (trace :io.perun/images-resize
151-
(meta-by-ext fileset [".png" ".jpeg" ".jpg"]))
152-
updated-metas (pod/with-call-in @pod
153-
(io.perun.contrib.images-resize/images-resize ~(.getPath tmp) ~metas ~options))]
154-
(perun/report-debug "images-resize" "new resized images" updated-metas)
155-
(-> fileset
156-
(commit tmp)
157-
(pm/set-meta updated-metas)))))
158-
159133
(defn apply-out-dir
160134
[path old-out-dir new-out-dir]
161135
(let [path-args (if (= old-out-dir new-out-dir)
@@ -238,9 +212,9 @@
238212
`passthru-fn` to handle setting changed metadata on files copied from the
239213
previous fileset. If input files should be removed from the fileset, set
240214
`rm-originals` to `true`."
241-
[{:keys [task-name render-form-fn paths-fn passthru-fn tracer pod rm-originals]}]
242-
(let [tmp (boot/tmp-dir!)
243-
prev (atom {})
215+
[{:keys [task-name render-form-fn paths-fn passthru-fn tracer pod tmp rm-originals]}]
216+
(let [prev (atom {})
217+
tmp (or tmp (boot/tmp-dir!))
244218
pod (or pod (create-pod content-deps))]
245219
(fn [next-task]
246220
(fn [fileset]
@@ -332,6 +306,69 @@
332306
(for [[path {:keys [entry]}] inputs]
333307
(merge entry (pm/path-meta path global-meta)))))
334308

309+
(defn resize-paths
310+
"Returns a map of path -> input for images-resize"
311+
[fileset {:keys [out-dir parent-path meta resolutions] :as options} tmp-dir]
312+
(let [global-meta (pm/get-global-meta fileset)
313+
files (boot/ls fileset)]
314+
(reduce
315+
(fn [result {:keys [slug path extension] :as entry}]
316+
(reduce
317+
(fn [result* resolution]
318+
(let [new-filename (str slug "_" resolution "." extension)
319+
new-path (-> (perun/create-filepath parent-path new-filename)
320+
(apply-out-dir (:out-dir entry) out-dir))
321+
input-file (first (boot/by-path [path] files))
322+
img-meta (assoc (pm/path-meta new-path global-meta)
323+
:resolution resolution
324+
:input-paths #{path}
325+
:input-meta (merge (pm/meta-from-file fileset input-file)
326+
(select-keys input-file [:hash]))
327+
:tmp-dir tmp-dir)]
328+
(assoc result*
329+
new-path (merge entry
330+
meta
331+
(when out-dir
332+
{:out-dir out-dir})
333+
img-meta))))
334+
result
335+
resolutions))
336+
{}
337+
(filter-meta-by-ext fileset options))))
338+
339+
(def ^:private ^:deps images-resize-deps
340+
'[[org.clojure/tools.namespace "0.3.0-alpha3"]
341+
[image-resizer "0.1.8"]])
342+
343+
(def ^:private +images-resize-defaults+
344+
{:out-dir "public"
345+
:resolutions #{3840 2560 1920 1280 1024 640}
346+
:filterer identity
347+
:extensions [".png" ".jpeg" ".jpg"]})
348+
349+
(deftask images-resize
350+
"Resize images to the provided resolutions.
351+
Each image file would have resolution appended to it's name:
352+
e.x. san-francisco.jpg would become san-francisco_3840.jpg"
353+
[o out-dir OUTDIR str "the output directory"
354+
r resolutions RESOLUTIONS #{int} "resolutions to which images should be resized"
355+
_ filterer FILTER code "predicate to use for selecting entries (default: `identity`)"
356+
e extensions EXTENSIONS [str] "extensions of files to include (default: `[]`, aka, all extensions)"
357+
m meta META edn "metadata to set on each entry"]
358+
;; This prevents a Java icon appearing in the dock on a Mac, and stealing program focus
359+
(System/setProperty "java.awt.headless" "true")
360+
(let [pod (create-pod images-resize-deps)
361+
tmp (boot/tmp-dir!)
362+
options (merge +images-resize-defaults+ *opts*)]
363+
(content-task
364+
{:render-form-fn (fn [data] `(io.perun.contrib.images-resize/image-resize ~data))
365+
:paths-fn #(resize-paths % options (.getPath tmp))
366+
:passthru-fn content-passthru
367+
:task-name "images-resize"
368+
:tracer :io.perun/images-resize
369+
:pod pod
370+
:tmp tmp})))
371+
335372
(def ^:private ^:deps yaml-metadata-deps
336373
'[[org.clojure/tools.namespace "0.3.0-alpha3"]
337374
[circleci/clj-yaml "0.5.5"]])

src/io/perun/contrib/images_resize.clj

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,29 @@
99
[java.awt.image BufferedImage]
1010
[javax.imageio ImageIO ImageWriter]))
1111

12-
(defn write-file [options tmp file ^BufferedImage buffered-file resolution]
13-
(let [{:keys [slug extension parent-path]} file
14-
new-filename (str slug "_" resolution "." extension)
15-
new-path (perun/create-filepath (:out-dir options) parent-path new-filename)
16-
new-file (io/file tmp new-path)]
17-
(io/make-parents new-file)
18-
(ImageIO/write buffered-file extension new-file)
19-
{:path new-path}))
20-
21-
(defn resize-to [tgt-path file options resolution]
22-
(let [io-file (-> file :full-path io/file)
23-
buffered-image (iu/buffered-image io-file)
24-
resized-buffered-image (resize/resize-to-width buffered-image resolution)
25-
new-dimensions (iu/dimensions resized-buffered-image)
26-
new-meta (write-file options tgt-path file resized-buffered-image resolution)
27-
dimensions {:width (first new-dimensions) :height (second new-dimensions)}]
28-
(merge file new-meta dimensions (select-keys options [:out-dir]))))
12+
(def img-cache (atom {}))
2913

30-
(defn process-image [tgt-path file options]
31-
(perun/report-debug "image-resize" "resizing" (:path file))
32-
(pmap #(resize-to tgt-path file options %) (:resolutions options)))
14+
(defn get-input-img
15+
[{:keys [input-meta]}]
16+
(let [input-path (:full-path input-meta)
17+
key (str input-path "-" (:hash input-meta))]
18+
(if-let [buffered-image (get @img-cache key)]
19+
@buffered-image
20+
(let [buffered-image (future (-> input-path
21+
io/file
22+
iu/buffered-image))]
23+
(swap! img-cache assoc key buffered-image)
24+
@buffered-image))))
3325

34-
(defn images-resize [tgt-path files options]
35-
(let [updated-files (doall (mapcat #(process-image tgt-path % options) files))]
36-
(perun/report-info "image-resize" "processed %s image files" (count files))
37-
updated-files))
26+
(defn image-resize
27+
[{:keys [path resolution extension tmp-dir] :as data}]
28+
(perun/report-debug "image-resize" "resizing" path)
29+
(let [buffered-image (get-input-img data)
30+
resized-buffered-image (resize/resize-to-width buffered-image resolution)
31+
new-file (io/file tmp-dir path)]
32+
(io/make-parents new-file)
33+
(ImageIO/write resized-buffered-image extension new-file)
34+
(merge (dissoc data :input-meta :tmp-dir)
35+
(into {} (map vector
36+
[:width :height]
37+
(iu/dimensions resized-buffered-image))))))

0 commit comments

Comments
 (0)