diff --git a/plug-ins/script-fu/scripts/meson.build b/plug-ins/script-fu/scripts/meson.build index fc55728340..d2b7fb38c3 100644 --- a/plug-ins/script-fu/scripts/meson.build +++ b/plug-ins/script-fu/scripts/meson.build @@ -41,6 +41,7 @@ scripts = [ 'slide.scm', 'spinning-globe.scm', 'tileblur.scm', + 'unsharp-mask.scm', 'waves-anim.scm', 'weave.scm', 'xach-effect.scm', diff --git a/plug-ins/script-fu/scripts/unsharp-mask.scm b/plug-ins/script-fu/scripts/unsharp-mask.scm new file mode 100644 index 0000000000..de512a10f6 --- /dev/null +++ b/plug-ins/script-fu/scripts/unsharp-mask.scm @@ -0,0 +1,105 @@ +;;; unsharp-mask.scm +;;; Time-stamp: <1998/11/17 13:18:39 narazaki@gimp.org> +;;; Author: Narazaki Shuji +;;; Version 0.8 + +; This script-fu-unsharp-mask is not in the menus. +; There is an equivalent GEGL filter at Filters>Enhance>Sharpen (Unsharp). +; This might be kept for compatibility and used by third party scripts. + +; Seems not used by any script in the repo. +; FUTURE move to gimp-data-extras or to scripts/test +; and maintain it with low priority. + +; unsharp-mask is a filter AND renderer, creating a new, visible, dirty image +; from the given image. + + +(define (script-fu-unsharp-mask img drws mask-size mask-opacity) + (let* ( + (drw (vector-ref drws 0)) + (drawable-width (car (gimp-drawable-get-width drw))) + (drawable-height (car (gimp-drawable-get-height drw))) + (new-image (car (gimp-image-new drawable-width drawable-height RGB))) + (original-layer (car (gimp-layer-new new-image "Original" + drawable-width drawable-height + RGB-IMAGE + 100 LAYER-MODE-NORMAL))) + (original-layer-for-darker 0) + (original-layer-for-lighter 0) + (blurred-layer-for-darker 0) + (blurred-layer-for-lighter 0) + (darker-layer 0) + (lighter-layer 0) + ) + + (gimp-selection-all img) + (gimp-edit-copy (vector drw)) + + (gimp-image-undo-disable new-image) + + (gimp-image-insert-layer new-image original-layer 0 0) + + (let* ( + (pasted (car (gimp-edit-paste original-layer FALSE))) + (num-pasted (vector-length pasted)) + (floating-sel (vector-ref pasted (- num-pasted 1))) + ) + (gimp-floating-sel-anchor floating-sel) + ) + + (set! original-layer-for-darker (car (gimp-layer-copy original-layer))) + (gimp-layer-add-alpha original-layer-for-darker) + (set! original-layer-for-lighter (car (gimp-layer-copy original-layer))) + (gimp-layer-add-alpha original-layer-for-lighter) + (set! blurred-layer-for-darker (car (gimp-layer-copy original-layer))) + (gimp-layer-add-alpha blurred-layer-for-darker) + (gimp-item-set-visible original-layer FALSE) + (gimp-display-new new-image) + + ;; make darker mask + (gimp-image-insert-layer new-image blurred-layer-for-darker 0 -1) + (gimp-drawable-merge-new-filter blurred-layer-for-darker "gegl:gaussian-blur" 0 LAYER-MODE-REPLACE 1.0 "std-dev-x" (* 0.32 mask-size) "std-dev-y" (* 0.32 mask-size) "filter" "auto") + (set! blurred-layer-for-lighter + (car (gimp-layer-copy blurred-layer-for-darker))) + (gimp-layer-add-alpha blurred-layer-for-lighter) + (gimp-image-insert-layer new-image original-layer-for-darker 0 -1) + (gimp-layer-set-mode original-layer-for-darker LAYER-MODE-SUBTRACT) + (set! darker-layer + (car (gimp-image-merge-visible-layers new-image CLIP-TO-IMAGE))) + (gimp-item-set-name darker-layer "darker mask") + (gimp-item-set-visible darker-layer FALSE) + + ;; make lighter mask + (gimp-image-insert-layer new-image original-layer-for-lighter 0 -1) + (gimp-image-insert-layer new-image blurred-layer-for-lighter 0 -1) + (gimp-layer-set-mode blurred-layer-for-lighter LAYER-MODE-SUBTRACT) + (set! lighter-layer + (car (gimp-image-merge-visible-layers new-image CLIP-TO-IMAGE))) + (gimp-item-set-name lighter-layer "lighter mask") + + ;; combine them + (gimp-item-set-visible original-layer TRUE) + (gimp-layer-set-mode darker-layer LAYER-MODE-SUBTRACT) + (gimp-layer-set-opacity darker-layer mask-opacity) + (gimp-item-set-visible darker-layer TRUE) + (gimp-layer-set-mode lighter-layer LAYER-MODE-ADDITION) + (gimp-layer-set-opacity lighter-layer mask-opacity) + (gimp-item-set-visible lighter-layer TRUE) + + (gimp-image-undo-enable new-image) + (gimp-displays-flush) + ) +) + +(script-fu-register-filter "script-fu-unsharp-mask" + "Unsharp Mask..." + "Make a new image from the current layer by applying the unsharp mask method" + "Shuji Narazaki " + "Shuji Narazaki" + "1997,1998" + "*" + SF-ONE-OR-MORE-DRAWABLE + SF-ADJUSTMENT _"Mask size" '(5 1 100 1 1 0 1) + SF-ADJUSTMENT _"Mask opacity" '(50 0 100 1 1 0 1) +) diff --git a/plug-ins/script-fu/test/tests/Plugins/noninteractive.scm b/plug-ins/script-fu/test/tests/Plugins/noninteractive.scm index 391d174469..1cdfeb681d 100644 --- a/plug-ins/script-fu/test/tests/Plugins/noninteractive.scm +++ b/plug-ins/script-fu/test/tests/Plugins/noninteractive.scm @@ -1,7 +1,8 @@ ; Test script calling plugin scripts non-interactive -; Some scripts must be non-interactive (no menu item.) -; Such scripts can only be tested by another plugin or script. +; Some are scripts that must be non-interactive (no menu item.) +; Most scripts can be tested using app menus. +; These scripts can only be tested by another plugin or script. ; This also tests and illustrates aspects ; of calling plugin scripts from other scripts: @@ -13,10 +14,6 @@ ; While calling a dialect v2 script interprocess ; can be done from v3 binding state. -; This also illustrates that some scripts are not well-behaved -; re non-interactive calls: -; they open a display on the new image. - ; FUTURE: call all plugin scripts in repo @@ -29,10 +26,10 @@ (define testImage (testing:load-test-image-basic-v3)) -; get-layers returns just a vector #(layers) +; get-layers returns (length #(layers)) ; Calling another script requires a vector of layers (ever since multi-layer feature.) - -(define testDrawables (gimp-image-get-layers testImage)) +; cdr is always a list i.e. (#(layers)), so we need cadr here. +(define testDrawables (cadr (gimp-image-get-layers testImage))) (define testDrawable (vector-ref testDrawables 0)) ;(newline) @@ -41,14 +38,15 @@ -(test! "Calling a Scheme plugin script non-interactively") +(test! "script-fu-unsharp-mask") -; The called plugin is a Scheme script that is already loaded in the interpreter. +; script-fu-unsharp-mask has been replaced by a GEGL filter. +; If it is removed from the repo, please keep a test of some script here, +; if only as an example of how the testing framework can test plugin scripts. -; The test is only: ensure it doesn't error or crash, -; and that it does not open a display on the new image +; The test is only: ensure it doesn't error or crash. -; The called plugin uses v2 binding +; unsharp-mask uses v2 binding ; If called without this, usually error is "must be pair" (script-fu-use-v2) @@ -58,16 +56,17 @@ ; only a call to a Scheme function, the run-func of the script. ; Use the Scheme signature of the run-func: ; no run_mode argument. -; -; The script is not a filter, but a renderer, -; and does not use passed image and drawables. - -(script-fu-gradient-example +; no "num-drawables" argument of the C signature. +(script-fu-unsharp-mask ; !!! Not pass run_mode - 40 40 ; dimensions of new image - 1 ; NO reverse gradient. Since v2 binding, this is a number, not #f + testImage + ; !!! Not pass num_drawables, just a Scheme vector of int ID of drawables + testDrawables + 128 ; mask-size, radius in pixels + 50 ; opacity percent ) -; Expect creates new image of current gradient in context +; Expect an image with extra layers: "lighter mask" and "darker mask" + ; back to v3 binding so we don't need to unwrap calls to gimp-foo in this scope. (script-fu-use-v3) @@ -120,6 +119,7 @@ (script-fu-test-sphere-v3 RUN-NONINTERACTIVE ; run_mode see above interprocess testImage ; unused Image + 1 ; num-drawables int size of GimpObjectArray testDrawables ; unused GimpObjectArray, Scheme vector of int ID ; radius is actually dimension of the square rendered image 300 ; radius int diff --git a/po-script-fu/POTFILES.in b/po-script-fu/POTFILES.in index 948f1e6dd5..1cda12a8ee 100644 --- a/po-script-fu/POTFILES.in +++ b/po-script-fu/POTFILES.in @@ -47,6 +47,7 @@ plug-ins/script-fu/scripts/slide.scm plug-ins/script-fu/scripts/spinning-globe.scm plug-ins/script-fu/scripts/test-sphere-v3.scm plug-ins/script-fu/scripts/tileblur.scm +plug-ins/script-fu/scripts/unsharp-mask.scm plug-ins/script-fu/scripts/waves-anim.scm plug-ins/script-fu/scripts/weave.scm plug-ins/script-fu/scripts/xach-effect.scm