1 ;;; album.el --- Photo album utility
3 ;; Copyright (C) 2005 MORIOKA Tomohiko
5 ;; Keywords: Photo, image, album, HTML, WWW
7 ;; This file is part of Album.
9 ;; Album is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; Album is distributed in the hope that it will be useful, but
15 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ;; General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
26 ;; It requires `convert' and `identify' of ImageMagick.
30 (defun album-make-spec-by-width (width limit spec-name)
32 (let ((percent (floor (/ (* limit 100.0) width))))
33 (vector percent spec-name
34 (/ (* width percent) 100.0)
35 (/ (* height percent) 100.0)))))
37 (defun album-make-spec-by-height (height limit spec-name)
38 (when (> height limit)
39 (let ((percent (floor (/ (* limit 100.0) height))))
40 (vector percent spec-name
41 (/ (* width percent) 100.0)
42 (/ (* height percent) 100.0)))))
44 (defun album-write-html (dest-dir lang image-url-prefix
45 prev-file file next-file
46 prev-grade grade next-grade)
49 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
50 \"http://www.w3.org/TR/html4/loose.dtd\">\n")
53 (insert (format " lang=\"%s\"" lang)))
56 (insert (format "<title>%s</title>\n" file))
59 (insert (format "<h1>%s</h1>\n" file))
62 (insert (format "<a href=\"%s.html\">" prev-file)))
69 (insert (format "<a href=\"%s.html\">" next-file)))
76 (insert (format "<a href=\"../%s/%s.html\">"
85 (insert (format "<a href=\"../%s/%s.html\">"
99 (format "../%s/%s.html" next-grade file)
100 (concat "../fullsize/" file ".jpg")))
102 (insert (format "<img alt=\"%s\" src=\"%s.jpg\">"
106 image-url-prefix grade file)
112 <a href=\"../index.html\">[index]</a>
117 (unless (file-exists-p
118 (expand-file-name (symbol-name grade) dest-dir))
120 (expand-file-name (symbol-name grade) dest-dir)))
121 (write-region (point-min)(point-max)
123 (concat file ".html")
124 (expand-file-name (symbol-name grade)
127 (defun album-convert-image (image-dest-dir html-dest-dir lang
129 prev-file file next-file)
130 (setq file (expand-file-name file))
131 (unless html-dest-dir
132 (setq html-dest-dir image-dest-dir))
135 (call-process "identify" nil t t file)
136 (goto-char (point-min))
137 (and (re-search-forward " \\([0-9]+\\)x\\([0-9]+\\) " nil t)
138 (cons (string-to-number (match-string 1))
139 (string-to-number (match-string 2))))))
144 (cond ((>= width height)
145 (when (setq ret (album-make-spec-by-width width 2048 'QXGA))
146 (setq dest (cons ret dest)))
147 (when (setq ret (album-make-spec-by-width width 1600 'UXGA))
148 (setq dest (cons ret dest)))
149 (when (setq ret (album-make-spec-by-width width 1400 'SXGA+))
150 (setq dest (cons ret dest)))
151 (when (setq ret (album-make-spec-by-width width 1280 'SXGA))
152 (setq dest (cons ret dest)))
153 (when (setq ret (album-make-spec-by-width width 1024 'XGA))
154 (setq dest (cons ret dest)))
155 (when (setq ret (album-make-spec-by-width width 800 'SVGA))
156 (setq dest (cons ret dest)))
157 (when (setq ret (album-make-spec-by-width width 640 'VGA))
158 (setq dest (cons ret dest)))
159 (when (setq ret (album-make-spec-by-width width 160 'thumbnail))
160 (setq dest (cons ret dest)))
163 (when (setq ret (album-make-spec-by-height height 1536 'QXGA))
164 (setq dest (cons ret dest)))
165 (when (setq ret (album-make-spec-by-height height 1200 'UXGA))
166 (setq dest (cons ret dest)))
167 (when (setq ret (album-make-spec-by-height height 1050 'SXGA+))
168 (setq dest (cons ret dest)))
169 (when (setq ret (album-make-spec-by-height height 960 'SXGA))
170 (setq dest (cons ret dest)))
171 (when (setq ret (album-make-spec-by-height height 768 'XGA))
172 (setq dest (cons ret dest)))
173 (when (setq ret (album-make-spec-by-height height 600 'SVGA))
174 (setq dest (cons ret dest)))
175 (when (setq ret (album-make-spec-by-height height 480 'VGA))
176 (setq dest (cons ret dest)))
177 (when (setq ret (album-make-spec-by-height height 160 'thumbnail))
178 (setq dest (cons ret dest)))
180 (unless (file-exists-p
181 (expand-file-name "thumbnail" image-dest-dir))
183 (expand-file-name "thumbnail" image-dest-dir)))
184 (call-process "convert" nil nil nil
185 "-resize" (format "%d%%" (aref (car dest) 0))
189 (file-name-sans-extension
190 (file-name-nondirectory file)) ".jpg")
194 (setq rest (cdr dest))
196 (setq spec (car rest))
197 (album-write-html html-dest-dir lang image-url-prefix
199 (file-name-sans-extension
200 (file-name-nondirectory prev-file)))
201 (file-name-sans-extension
202 (file-name-nondirectory file))
204 (file-name-sans-extension
205 (file-name-nondirectory next-file)))
209 (aref (nth 1 rest) 1)))
210 (call-process "convert" nil nil nil
211 "-resize" (format "%d%%" (aref spec 0))
215 (file-name-sans-extension
216 (file-name-nondirectory file)) ".jpg")
218 (symbol-name (aref spec 1))
220 (setq prev-grade (aref spec 1))
221 (setq rest (cdr rest)))
222 (unless (file-exists-p
223 (expand-file-name "fullsize" image-dest-dir))
225 (expand-file-name "fullsize" image-dest-dir)))
226 (if (string= (downcase (file-name-extension file))
228 (call-process "ln" nil nil nil
231 (expand-file-name "fullsize" image-dest-dir))
232 (call-process "convert" nil nil nil
236 (file-name-sans-extension
237 (file-name-nondirectory file)) ".jpg")
238 (expand-file-name "fullsize" image-dest-dir))))
241 (defun album-convert-images (image-dest-dir html-dest-dir lang
244 (unless html-dest-dir
245 (setq html-dest-dir image-dest-dir))
246 (if (and (consp (car source-images))
247 (null (cdr source-images)))
248 (setq source-images (car source-images)))
249 (album-make-thumbnails html-dest-dir lang image-url-prefix
251 (let (file prev-file)
253 (setq file (car source-images))
254 (album-convert-image image-dest-dir html-dest-dir lang
256 prev-file file (nth 1 source-images))
258 source-images (cdr source-images)))))
260 (defun album-make-thumbnails (html-dest-dir lang image-url-prefix
263 (file-name-nondirectory
264 (if (eq (aref html-dest-dir (1- (length html-dest-dir))) ?/)
265 (substring html-dest-dir 0 (1- (length html-dest-dir)))
270 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
271 \"http://www.w3.org/TR/html4/loose.dtd\">\n")
274 (insert (format " lang=\"%s\"" lang)))
277 (insert (format "<title>%s</title>\n" album))
280 (insert (format "<h1>%s</h1>\n" album))
285 (dolist (image-file source-images)
286 (setq file (file-name-sans-extension
287 (file-name-nondirectory image-file)))
288 (insert "<a href=\"VGA/")
291 (insert (format "<img alt=\"%s\" src=\"thumbnail/%s.jpg\">"
295 image-url-prefix grade file)
305 (write-region (point-min)(point-max)
306 (expand-file-name "index.html" html-dest-dir)))))
308 (defun album-convert-directory (image-dest-dir html-dest-dir lang
310 source-dir &rest patterns)
313 (dolist (pat patterns)
316 (directory-files source-dir 'full pat))))
318 (let (case-fold-search)
321 ".+\\.\\(tiff\\|jpg\\|JPG\\|jpeg\\|gif\\|png\\)$"))))
322 (album-convert-images image-dest-dir html-dest-dir lang
323 image-url-prefix files)))
328 ;;; album.el ends here