; merge-anim.scm - Merge the bg or top layer of an image with all other layers. ; Copyright (C) 1998 Raphael Quinet ; ; 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. ; ; --- Description --- ; This script allows you to add a background to an existing animation, ; or to add some object on top of all frames. You can optionally add ; fade-in/fade-out effects or some movement by varying the opacity and ; position of the merged layers. ; The script does nothing more than repeatedly copying the new layer ; and merging it with each of the other layers. You could also do this ; by hand, but this is a boring task. That's why I wrote this script. ; ; --- Change log --- ; 1.0 - 1998-08-10 ; First public release. ; 1.1 - 1998-08-11 ; Merged 'merge-bg.scm' and 'merge-top.scm' into a single script ; named 'merge-anim.scm'. Someone should write 'merge-scm.scm'... ; 1.2 - 1998-08-11 ; Added GRAYA to the list of supported image types (RGB and GRAY ; without alpha would not work because we need two layers). (define (script-fu-merge-anim image drawable src-is-bg visible-only delete-src i-opacity f-opacity transform-anim i-offset-x i-offset-y f-offset-x f-offset-y) (let* ((layers (gimp-image-get-layers image)) (num-layers (car layers)) (layer-array (cadr layers)) (diff-opacity (- i-opacity f-opacity)) (diff-offset-x (- i-offset-x f-offset-x)) (diff-offset-y (- i-offset-y f-offset-y))) (if (> num-layers 1) (let* ((visi-array (cons-array num-layers)) (num-vlayers (- num-layers 1)) (src-layer (aref layer-array (if (= src-is-bg TRUE) num-vlayers 0)))) (gimp-image-disable-undo image) ; hide all layers (visi-array keeps track of which ones were visible) (set! layer-count (- num-layers 1)) (while (>= layer-count 0) (let* ((layer (aref layer-array layer-count)) (visible (car (gimp-layer-get-visible layer)))) (aset visi-array layer-count visible) (if (and (= visible-only TRUE) (= visible FALSE)) (set! num-vlayers (- num-vlayers 1))) (gimp-layer-set-visible layer FALSE)) (set! layer-count (- layer-count 1))) (set! vlayer-count num-vlayers) (set! layer-count (- num-layers (if (= src-is-bg TRUE) 2 1))) (if (> num-vlayers 0) (while (>= layer-count (if (= src-is-bg TRUE) 0 1)) (let* ((layer (aref layer-array layer-count)) (was-visible (aref visi-array layer-count))) (if (or (= visible-only FALSE) (= was-visible TRUE)) (let* ((new-layer (car (gimp-layer-copy src-layer TRUE))) (new-name (car (gimp-layer-get-name layer))) (opacity (+ f-opacity (/ (* diff-opacity vlayer-count) num-vlayers))) (offset-x (+ f-offset-x (/ (* diff-offset-x vlayer-count) num-vlayers))) (offset-y (+ f-offset-y (/ (* diff-offset-y vlayer-count) num-vlayers))) (offset-layer (if (= transform-anim TRUE) layer new-layer))) ; add the copy of the source layer (gimp-image-add-layer image new-layer (+ layer-count (if (= src-is-bg TRUE) 1 0))) ; make both layers visible (gimp-layer-set-visible new-layer TRUE) (gimp-layer-set-visible layer TRUE) ; change the opacity of the top layer (gimp-layer-set-opacity (if (= src-is-bg TRUE) layer new-layer) opacity) ; if specified, move one of the layers (if (not (and (= offset-x 0) (= offset-y 0))) (gimp-channel-ops-offset image offset-layer TRUE 0 offset-x offset-y)) ; merge them (set! merged-layer (car (gimp-image-merge-visible-layers image CLIP-TO-IMAGE))) (aset layer-array layer-count merged-layer) (gimp-layer-set-name merged-layer new-name) ; hide the result (gimp-layer-set-visible merged-layer FALSE) (set! vlayer-count (- vlayer-count 1))))) (set! layer-count (- layer-count 1))) ; ...else num-vlayers <= 0 (gimp-message "There are no visible layers in the image!")) ; restore the visibility of all layers (set! layer-count (- num-layers 1)) (while (>= layer-count 0) (let* ((layer (aref layer-array layer-count)) (visible (aref visi-array layer-count))) (gimp-layer-set-visible layer visible)) (set! layer-count (- layer-count 1))) (if (and (= delete-src TRUE) (> num-vlayers 0)) (gimp-image-remove-layer image (aref layer-array (if (= src-is-bg TRUE) (- num-layers 1) 0)))) ; that's all, folks! (gimp-image-enable-undo image) (gimp-displays-flush)) ; ...else num-layers <= 1 (gimp-message "The source image must have at least two layers")))) (script-fu-register "script-fu-merge-anim" "/Script-Fu/Animators/Merge layer with others" "Merge the background or top layer with all other layers in the image" "Raphael Quinet " "Raphael Quinet" "1998-08-11" "RGBA GRAYA" SF-IMAGE "Input Image" 0 SF-DRAWABLE "Input Drawable" 0 SF-TOGGLE "Merge with bg (else top)?" TRUE SF-TOGGLE "Visible layers only?" TRUE SF-TOGGLE "Delete bg/top after merge?" TRUE SF-VALUE "Initial opacity (%)" "100.0" SF-VALUE "Final opacity (%)" "100.0" SF-TOGGLE "Offset anim instead of bg/top?" FALSE SF-VALUE "Initial X offset" "0" SF-VALUE "Initial Y offset" "0" SF-VALUE "Final X offset" "0" SF-VALUE "Final Y offset" "0" )