2 hours ago
Hello,
with Gimp 2.8 I have an scm script (I found somewhere) that runs perfect on one image when called from the menu within gimp. Now I'd like to run it for a whole directory and wrote a bash script for this.
It works in general, but when running the script on a single image within the Gimp, it creates a group with two layers and places this group above the original image layer. But when running it as a batch with my bash script, the original image layer is inserted within the new group.
Neither grok nor chat gpt could help me successfully :-)
Can you hint me what to change, so that the original image layer stays as a separate layer outside (below) the new layer-group?
(B.t.w., I have literally no idea of Gimp scripting, am just capable to use and adapt a little scripts I find somewhere :-) )
This is my bash script:
This is the scm script:
with Gimp 2.8 I have an scm script (I found somewhere) that runs perfect on one image when called from the menu within gimp. Now I'd like to run it for a whole directory and wrote a bash script for this.
It works in general, but when running the script on a single image within the Gimp, it creates a group with two layers and places this group above the original image layer. But when running it as a batch with my bash script, the original image layer is inserted within the new group.
Neither grok nor chat gpt could help me successfully :-)
Can you hint me what to change, so that the original image layer stays as a separate layer outside (below) the new layer-group?
(B.t.w., I have literally no idea of Gimp scripting, am just capable to use and adapt a little scripts I find somewhere :-) )
This is my bash script:
Code:
#!/bin/bash
INPUT_DIR="..."
OUTPUT_SUFFIX=".xcf"
BLUR=15
VISIBLE="FALSE"
for file in "$INPUT_DIR"/*.{jpg,png,tif,bmp}; do
if [ -f "$file" ]; then
output_file="${file%.*}${OUTPUT_SUFFIX}"
gimp -i -b "
(let*
(
(filename \"$file\")
(image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
;; Bottom layer = original image
(layer-info (gimp-image-get-layers image))
(drawable (vector-ref (cadr layer-info) 0))
;; Extract name
(fname (car (reverse (strbreakup filename \"/\"))))
(basename (car (strbreakup fname \".\")))
)
;; Rename to match GUI
(gimp-item-set-name drawable basename)
;; select this layer before FS script
(gimp-image-set-active-layer image drawable)
;; Run FS
(script-fu-hk-frequency-separation image drawable $BLUR $VISIBLE)
;; Save
(gimp-xcf-save RUN-NONINTERACTIVE image drawable \"$output_file\" \"$output_file\")
(gimp-image-delete image)
)
" -b '(gimp-quit 0)'
echo "Processed: $file -> $output_file"
fi
done This is the scm script:
Code:
; This plugin was tested with Gimp 2.8.3
; This plugin will not work for Gimp 2.6.x because of the unknown layer group
;
; frequency-separartion.scm
; seperates a layer or the whole visible into a
; layer group with high- and low frequency parts
;
; 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.
;
(define LList '())
(define (makelist E) (list E))
(define (isempty L) (null? L))
(define (add E L) (cons E L))
(define (Ith i L)
(if (= i 1)
(car L)
(Ith (- i 1) (cdr L))))
(define (fs-set-layers-visible inImage)
(let*
(
(num-layers (length LList))
(theLayer 0)
)
(while (> num-layers 0)
(set! theLayer (Ith num-layers LList))
(gimp-drawable-set-visible theLayer TRUE)
(set! num-layers (- num-layers 1))
)
; (gimp-displays-flush)
(set! LList (list))
)
)
(define (fs-set-layers-invisible inImage inLayer)
(let*
(
(layers (gimp-image-get-layers inImage))
(num-layers (car layers))
(layer-array (cadr layers))
(theLayer 0)
)
(while (> num-layers 0)
(set! num-layers (- num-layers 1))
(set! theLayer (vector-ref layer-array num-layers))
(if (= (car (gimp-drawable-get-visible theLayer) ) TRUE)
(if (<> theLayer inLayer)
(begin
(gimp-drawable-set-visible theLayer FALSE)
(set! LList (cons theLayer LList))
)
)
)
)
; (gimp-displays-flush)
)
)
(define (script-fu-hk-frequency-separation image layer blur visible)
(let*
(
; test, whether seperating a layer group
(isgroup (car (gimp-item-is-group layer)))
; get parent, maybe layer group
(parent (car (gimp-item-get-parent layer)))
; get layername
(layername (car (gimp-item-get-name layer)))
; gets position of layer
(position (car (gimp-image-get-item-position image layer)))
; creates layergroup
(fs-layergroup (car (gimp-layer-group-new image)))
; variables
(helplayer 0)
(lowlayer 0)
(highlayer 0)
(forceVisible 0)
(viewmode 0)
(opacity 0)
)
; FALSE=freqsep just the layer
; TRUE=freqsep from new visible
(if (= visible FALSE)
(begin
(if (= isgroup 1)
(begin
(set! forceVisible 1)
)
(begin
(set! forceVisible 0)
)
)
)
(begin
(set! forceVisible 1)
)
)
(gimp-image-undo-group-start image)
(if (= forceVisible 0)
(begin
(fs-set-layers-invisible image layer)
)
)
;rename layergroup
(gimp-item-set-name fs-layergroup "frequency separation")
;add layergroup as first to the image layer-stack
(gimp-image-insert-layer image fs-layergroup 0 0)
; 0=freqsep just the layer
; 1=freqsep from new visible
(if (= forceVisible 0)
(begin
(set! viewmode (car (gimp-layer-get-mode layer)))
(set! opacity (car (gimp-layer-get-opacity layer)))
(gimp-image-reorder-item image layer fs-layergroup -1)
(gimp-layer-set-mode layer NORMAL-MODE)
(gimp-layer-set-opacity layer 100)
(set! helplayer (car (gimp-layer-copy layer 1)))
(set! lowlayer (car (gimp-layer-copy layer 1)))
(gimp-drawable-set-name helplayer (string-append "help-" layername))
(gimp-drawable-set-name lowlayer (string-append "low-" layername))
)
(begin
(set! helplayer (car (gimp-layer-new-from-visible image image "helplayer")))
(set! lowlayer (car (gimp-layer-new-from-visible image image "low")))
)
)
; adding layers to layergroup
(gimp-image-insert-layer image helplayer fs-layergroup -1)
(gimp-image-insert-layer image lowlayer fs-layergroup -1)
; despeckle the low frequency layer
(plug-in-gauss 1 image lowlayer blur blur 1)
; setting layer mode to get the high frequency layer
(gimp-layer-set-mode lowlayer GRAIN-EXTRACT-MODE)
; getting the high frequency layer. that works, because the lauergroup is topmost
(set! highlayer (car (gimp-layer-new-from-visible image image (string-append "high-" layername))))
; add it it to the layergroup
(gimp-image-insert-layer image highlayer fs-layergroup -1)
; remove the helping layer
(gimp-image-remove-layer image helplayer)
; make the low frequency layer normal
(gimp-layer-set-mode lowlayer NORMAL-MODE)
; make the high frequency layer grain-merge, so the result is the image
(gimp-layer-set-mode highlayer GRAIN-MERGE-MODE)
; put the layergroup just above the layer, that was selected
(gimp-image-reorder-item image fs-layergroup parent position)
(if (= forceVisible 0)
(begin
; restore viewmode and opacity, now for the whole layergroup.
(gimp-layer-set-mode fs-layergroup viewmode)
(gimp-layer-set-opacity fs-layergroup opacity)
(fs-set-layers-visible image)
)
)
(gimp-image-set-active-layer image lowlayer)
(gimp-displays-flush)
(gimp-image-undo-group-end image)
)
)
(script-fu-register "script-fu-hk-frequency-separation"
"Frequency separation..."
"frequency-separation.scm
divides layer in high and low frequencies"
"H.Kuhse"
"H.Kuhse"
"2013-01-04"
"*"
SF-IMAGE "Image" 0
SF-DRAWABLE "Layer" 0
SF-ADJUSTMENT _"Blur:" '(15 1 50 1 1 0 0)
SF-TOGGLE _"from visible (instead selected layer)" 1
)
(script-fu-menu-register
"script-fu-hk-frequency-separation"
"<Image>/Filters"
)
