Gimp-Forum.net

Full Version: How to change a script to work with alpha channel?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
There is a script called 'tile_shuffle.scm', and I want to edit it a little.

This script does not work with alpha channels.  Is there any way to edit it to shuffle tiles with alpha values?
 

Here's the script:

Code:
; tile_shuffle.scm
; by Rob Antonishen
; http://ffaat.pointclark.net

; Version 1.0 (20090118)

; Description
; Shuffles tiles of the image

; License:
;
; 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.
;
; The GNU Public License is available at
; http://www.gnu.org/copyleft/gpl.html
(define (script-fu-tile_shuffle img inLayer inX inY)
(let* (
        (width (car (gimp-image-width img)))
        (height (car (gimp-image-height img)))
        (inX (min inX width))
        (inY (min inY height))        
        (xTiles (trunc (/ width inX)))
        (yTiles (trunc (/ height inY)))        
        (tile1 0)
        (newlayer 0)
        (x0 0)
        (y0 0)
        (x1 0)
        (y1 0)
        (counter 0)
        (swap 0)
        (temp 0)
        (tilelist (cons-array (* xTiles yTiles) 'double))
        (mode (car (gimp-layer-get-mode inLayer)))
        )

    (gimp-context-push)
    (gimp-image-undo-group-start img)
    ; set up progress bar
    (gimp-progress-set-text _"Shuffling Tiles")
    
    ;fill list
    (while (< counter (* xTiles yTiles))
    (begin
        (aset tilelist counter counter)
        (set! counter (+ counter 1))
    )
    )
    
    ;shuffle list
    (while (> counter 1)
    (begin
        (set! swap (rand counter))
        (set! counter (- counter 1))
        (set! temp (vector-ref tilelist counter))
        (aset tilelist counter (vector-ref tilelist swap))
        (aset tilelist swap temp)
    )
    )

    ;create a working layer
    (set! newlayer (car (gimp-layer-new-from-drawable inLayer img)))
    (gimp-image-add-layer img newlayer (car (gimp-image-get-layer-position img inLayer)))        
    (gimp-layer-set-mode newlayer NORMAL-MODE)

    ;cut and paste tiles based on the shuffled array
    (set! counter 0)
    (while (< counter  (* xTiles yTiles) )
    (begin
        (gimp-progress-update (/ counter (+ (* xTiles yTiles) (if (> (remainder width inX) 0) yTiles 0) (if (> (remainder height inY) 0) xTiles 0) )))  ;update progress bar
        (set! x0 (* (* (remainder counter xTiles)) inX))
        (set! y0 (* (trunc (/ counter xTiles)) inY))

        (set! x1 (* (* (remainder (vector-ref tilelist counter) xTiles)) inX))
        (set! y1 (* (trunc (/ (vector-ref tilelist counter) xTiles)) inY))
        
        (gimp-rect-select img x0 y0 inX inY CHANNEL-OP-REPLACE FALSE 0)
        (gimp-edit-copy inLayer)
        (set! tile1 (car (gimp-edit-paste newlayer FALSE)))

        (set! tile1 (car (gimp-drawable-transform-2d-default tile1 x0 y0 1 1 0 x1 y1 FALSE 0)))
        
        (set! counter (+ counter 1))
    )
    )    
    (gimp-floating-sel-anchor tile1)

    ;edge tiles
    (if (> (remainder width inX) 0)
    (begin
        (set! tilelist (cons-array yTiles 'double))
        (set! counter 0)
        ;fill list
        (while (< counter yTiles)
        (begin
            (aset tilelist counter counter)
            (set! counter (+ counter 1))
        )
        )

        ;shuffle list
        (while (> counter 1)
        (begin
            (set! swap (rand counter))
            (set! counter (- counter 1))
            (set! temp (vector-ref tilelist counter))
            (aset tilelist counter (vector-ref tilelist swap))
            (aset tilelist swap temp)
        )
        )

        ;vertical edge
        (set! x0 (* xTiles inX))
        (set! x1 (* xTiles inX))
        
        ;cut and paste tiles based on the shuffled array
        (set! counter 0)
        (while (< counter yTiles)
        (begin
            (gimp-progress-update (/ (+ counter (* xTiles yTiles)) (+ (* xTiles yTiles) (if (> (remainder width inX) 0) yTiles 0) (if (> (remainder height inY) 0) xTiles 0))))  ;update progress bar
            (set! y0 (* counter inY))
            (set! y1 (* (vector-ref tilelist counter) inY))
        
            (gimp-rect-select img x0 y0 (remainder width inX) inY CHANNEL-OP-REPLACE FALSE 0)
            (gimp-edit-copy inLayer)
            (set! tile1 (car (gimp-edit-paste newlayer FALSE)))

            (set! tile1 (car (gimp-drawable-transform-2d-default tile1 x0 y0 1 1 0 x1 y1 FALSE 0)))
        
            (set! counter (+ counter 1))
        )
        )
        (gimp-floating-sel-anchor tile1)
    )
    )

    ;edge tiles
    (if (> (remainder height inY) 0)
    (begin
        (set! tilelist (cons-array xTiles 'double))
        (set! counter 0)
        ;fill list
        (while (< counter xTiles)
        (begin
            (aset tilelist counter counter)
            (set! counter (+ counter 1))
        )
        )

        ;shuffle list
        (while (> counter 1)
        (begin
            (set! swap (rand counter))
            (set! counter (- counter 1))
            (set! temp (vector-ref tilelist counter))
            (aset tilelist counter (vector-ref tilelist swap))
            (aset tilelist swap temp)
        )
        )

        ;horizontal edge
        (set! y0 (* yTiles inY))
        (set! y1 (* yTiles inY))

        ;cut and paste tiles based on the shuffled array
        (set! counter 0)
        (while (< counter xTiles)
        (begin
            (gimp-progress-update (/ (+ counter (* xTiles yTiles) xTiles) (+ (* xTiles yTiles) (if (> (remainder width inX) 0) yTiles 0) (if (> (remainder height inY) 0) xTiles 0))))  ;update progress bar
            (set! x0 (* counter inX))
            (set! x1 (* (vector-ref tilelist counter) inX))
        
            (gimp-rect-select img x0 y0 inX (remainder height inY) CHANNEL-OP-REPLACE FALSE 0)
            (gimp-edit-copy inLayer)
            (set! tile1 (car (gimp-edit-paste newlayer FALSE)))

            (set! tile1 (car (gimp-drawable-transform-2d-default tile1 x0 y0 1 1 0 x1 y1 FALSE 0)))
        
            (set! counter (+ counter 1))
        )
        )
        (gimp-floating-sel-anchor tile1)
        
    )
    )

    (set! inLayer (car (gimp-image-merge-down img newlayer  EXPAND-AS-NECESSARY)))
    (gimp-layer-set-mode inLayer mode)
    
    (gimp-progress-end)
    (gimp-image-undo-group-end img)
    (gimp-displays-flush)
    (gimp-context-pop)
)
)


(script-fu-register "script-fu-tile_shuffle"
                    "<Image>/Filters/Distorts/_Tile Shuffle..."
                    "Shuffles image tiles"
                    "Rob Antonishen"
                    "Rob Antonishen"
                    "Jan 2009"
                    "RGB* GRAY*"
                    SF-IMAGE       "Image"         0
                    SF-DRAWABLE    "Drawable"      0
                    SF-ADJUSTMENT  "Tile X Size"          (list 100 4 1000 1 10 0 SF-SLIDER)
                    SF-ADJUSTMENT  "Tile Y Size"          (list 100 4 1000 1 10 0 SF-SLIDER)
                    )
In what way does it "not work" ?

I can see from the code that it will let you run it on images with alpha channels, so can you be more specific please.

Also, you could ask the author of the script. He has been known to post on GimpChat as RobA
If the layer I am shuffling has transparent pixels, then the results of the shuffle print over the original.

Perhaps the solution is to do the results in a new layer?
I can generate some error messages if the layer size is not equal to the image size. That stopped the transformation and produced 2 layers, so you get an overlay.

Worth applying Layer -> layer to image size.

Otherwise, a simple case and it works here, with a tiny transparent border Wink

Before: https://i.imgur.com/KDRyv22.jpg
After: https://i.imgur.com/uCbwQ0z.jpg

Edit: OK, just tried again with full transparency and I get an overlaid image. I guess the simple solution is have a solid background, then after a shuffle use color-to-alpha.

This one -> New from visible -> shuffle -> color-to-alpha on result.
[Image: Nx5A0Ny.jpg]
That would work in some cases.

Color to alpha doesn't really work in lots of cases. Unless I don't understand how color to alpha really works. My above example is just an extreme basic example; I often use lots of colors and some slight blurring. Color to alpha produces strange results most of the time.

Do you know how some scripts create the results in a new layer? I need to learn how to do that with this to work. Perhaps I should try to find RobA, because I use lots of his scripts.
Quote:Perhaps I should try to find RobA, because I use lots of his scripts.

As Kevins post, your best bet is gimpchat.com and a PM. He is no. 2 in members starting with R.

He did start a blog, looks abandoned, a message might/might not get through. http://www.silent9.com/blog/

and FWIW he is on twitter https://twitter.com/robantonishen