; The GIMP -- an image manipulation program ; Copyright (C) 1995 Spencer Kimball and Peter Mattis ; ; ; FujiCleaver ; Copyright (c) 1999 Matthew Marjanovic ; http://www.mir.com/Gimp/ ; ; ; The Fuji MX-700 digital still camera has a mode which takes 16 quick ; exposures, arrayed in a grid on a single image. ; This is a set of Script-Fu scripts which will extract and/or collate ; the images --- very convenient for making little animations. ; ; ---------------------------------------------------------------------- ; History ; ; 1998-02-11: v1.0 - initial release ; ---------------------------------------------------------------------- ; ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; Calculate relevant dimensions from source image, ; or exit with a message if the image is obviously not the right size. (define (figure-dimensions-or-bug-out drawable) (let ((image-width (car (gimp-drawable-width drawable))) (image-height (car (gimp-drawable-height drawable))) ) (cond ((and (= image-width 640) (= image-height 480)) (list 144 ; frame width 108 ; frame height 8 ; origin x 6 ; origin y 160 ; diff x 120 ; diff y )) ((and (= image-width 1280) (= image-height 1024)) (list 288 ; frame width 216 ; frame height 16 ; origin x 44 ; origin y 320 ; diff x 240 ; diff y )) (t (gimp-message "SORRY!\nThis script will only operate on an original\n1280x1024 or 640x480 multi-exposure image\nfrom a Fujifilm digital camera.") (*throw 'bug-out ()) ) ) )) ; Extract a frame (given by origin position) from source image, ; and copy to a new layer in destination image. (define (extract-rect src-img src-layer dest-img draw-type x y name dims) (let ((width (nth 0 dims)) (height (nth 1 dims)) ) (gimp-rect-select src-img x y width height REPLACE FALSE 0) (gimp-edit-copy src-img src-layer) (let ((new-layer (car (gimp-layer-new dest-img width height draw-type name 100 NORMAL)))) (gimp-image-add-layer dest-img new-layer 0) (gimp-floating-sel-anchor (car (gimp-edit-paste dest-img new-layer FALSE))) ) )) ; Extract a frame (given by row, column) from source image, ; and copy to a new layer in destination image. (define (extract-frame src-img src-layer dest-img draw-type row col name dims) (let ((origin-x (nth 2 dims)) (origin-y (nth 3 dims)) (diff-x (nth 4 dims)) (diff-y (nth 5 dims)) ) (extract-rect src-img src-layer dest-img draw-type (+ origin-x (* col diff-x)) (+ origin-y (* row diff-y)) name dims) )) ; Extract toggle frames from source image into separate new images (define (script-fu-fujicleaver-pick inImage inDrawable b00 b01 b02 b03 b10 b11 b12 b13 b20 b21 b22 b23 b30 b31 b32 b33) (*catch 'bug-out (let* ((dims (figure-dimensions-or-bug-out inDrawable)) (image-type (car (gimp-image-base-type inImage))) (draw-type (car (gimp-drawable-type-with-alpha inDrawable))) (frameWidth (nth 0 dims)) (frameHeight (nth 1 dims)) (picklist (list b00 b01 b02 b03 b10 b11 b12 b13 b20 b21 b22 b23 b30 b31 b32 b33)) (orig-selection (car (gimp-selection-save inImage))) ) (define (pick-iter pick-list row col) (if (not (null? pick-list)) (begin (if (= (car pick-list) TRUE) (let ((new-image (car (gimp-image-new frameWidth frameHeight image-type)))) (extract-frame inImage inDrawable new-image draw-type row col (string-append "Frame " (number->string row) "," (number->string col) ) dims) (gimp-display-new new-image) )) (pick-iter (cdr pick-list) (if (< col 3) row (+ row 1)) (if (< col 3) (+ col 1) 0)) )) ) (pick-iter picklist 0 0) (gimp-selection-load inImage orig-selection) (gimp-image-remove-channel inImage orig-selection) (gimp-displays-flush) )) ) ; Extract all frame from source image into layers in a new image. ; Optionally add duration codes (for animation) to layer names. ; Optionally make a second copy of layers in reverse order. (define (script-fu-fujicleaver-anim inImage inDrawable inCues inDelay inPing) (*catch 'bug-out (let* ((dims (figure-dimensions-or-bug-out inDrawable)) (image-type (car (gimp-image-base-type inImage))) (draw-type (car (gimp-drawable-type-with-alpha inDrawable))) (frameWidth (nth 0 dims)) (frameHeight (nth 1 dims)) (origin-x (nth 2 dims)) (origin-y (nth 3 dims)) (diff-x (nth 4 dims)) (diff-y (nth 5 dims)) (new-image (car (gimp-image-new frameWidth frameHeight image-type))) (orig-selection (car (gimp-selection-save inImage))) ) (define (extract-iter n nx ny x y) (if (< n 16) (begin (extract-rect inImage inDrawable new-image draw-type x y (if (= inCues TRUE) (string-append (number->string n) " (" (number->string inDelay) "ms)") (number->string n)) dims) (extract-iter (+ n 1) (if (< nx 3) (+ nx 1) 0) (if (< nx 3) ny (+ ny 1)) (if (< nx 3) (+ x diff-x) origin-x) (if (< nx 3) y (+ y diff-y))) ))) (define (reverse-iter n layers) (if (< n 15) (begin (gimp-image-add-layer new-image (car (gimp-layer-copy (aref layers n) FALSE)) 0) (reverse-iter (+ n 1) layers) ))) (extract-iter 0 0 0 origin-x origin-y) (if (= inPing TRUE) (reverse-iter 1 (cadr (gimp-image-get-layers new-image)))) (gimp-selection-load inImage orig-selection) (gimp-image-remove-channel inImage orig-selection) (gimp-display-new new-image) (gimp-displays-flush) ) ) ) ; Register the scripts! (script-fu-register "script-fu-fujicleaver-anim" "/Script-Fu/Alchemy/Fuji Cleaver/Make Layers, Animation" "Cleave a multi-exposure Fuji MX-700 image into parts" "Matt Marjanovic " "copyright 1999, Matt Marjanovic" "February 8, 1999" "RGB*, GRAY*" SF-IMAGE "Image to cleave" 0 SF-DRAWABLE "Drawable to cleave" 0 SF-TOGGLE "Add duration cues?" TRUE SF-VALUE "Layer duration (ms)" "125" SF-TOGGLE "Ping-pong" FALSE ) (script-fu-register "script-fu-fujicleaver-pick" "/Script-Fu/Alchemy/Fuji Cleaver/Pick Images" "Cleave a multi-exposure Fuji MX-700 image into parts" "Matt Marjanovic " "copyright 1999, Matt Marjanovic" "February 8, 1999" "RGB*, GRAY*" SF-IMAGE "Image to cleave" 0 SF-DRAWABLE "Drawable to cleave" 0 SF-TOGGLE "Extract #0 (0,0)" FALSE SF-TOGGLE "Extract #1 (0,1)" FALSE SF-TOGGLE "Extract #2 (0,2)" FALSE SF-TOGGLE "Extract #3 (0,3)" FALSE SF-TOGGLE "Extract #4 (1,0)" FALSE SF-TOGGLE "Extract #5 (1,1)" FALSE SF-TOGGLE "Extract #6 (1,2)" FALSE SF-TOGGLE "Extract #7 (1,3)" FALSE SF-TOGGLE "Extract #8 (2,0)" FALSE SF-TOGGLE "Extract #9 (2,1)" FALSE SF-TOGGLE "Extract #10 (2,2)" FALSE SF-TOGGLE "Extract #11 (2,3)" FALSE SF-TOGGLE "Extract #12 (3,0)" FALSE SF-TOGGLE "Extract #13 (3,1)" FALSE SF-TOGGLE "Extract #14 (3,2)" FALSE SF-TOGGLE "Extract #15 (3,3)" FALSE ) ; (script-fu-register "script-fu-fujicleaver-img-all" ; "/Script-Fu/Alchemy/Fuji Cleaver/All Images" ; "Cleave a multi-exposure Fuji MX-700 image into parts" ; "Matt Marjanovic " ; "copyright 1999, Matt Marjanovic" ; "February 8, 1999" ; "RGB*, GRAY*" ; SF-IMAGE "Image to cleave" 0 ; SF-DRAWABLE "Drawable to cleave" 0 ; )