Gimp-Forum.net
Add new paint method ? - Printable Version

+- Gimp-Forum.net (https://www.gimp-forum.net)
+-- Forum: GIMP (https://www.gimp-forum.net/Forum-GIMP)
+--- Forum: Extending the GIMP (https://www.gimp-forum.net/Forum-Extending-the-GIMP)
+---- Forum: Scripting questions (https://www.gimp-forum.net/Forum-Scripting-questions)
+---- Thread: Add new paint method ? (/Thread-Add-new-paint-method)

Pages: 1 2


Add new paint method ? - Jack Parker - 02-03-2019

Is there a way (short of C code and recompiling GIMP) to add a custom paint-method?
I'd like to add a new painter to the list (gimp-context-list-paint-methods) 
So that (gimp-drawable-edit-stroke-selection drawable) will do a custom procedural edit to the pixels.


RE: Add new paint method ? - Ofnuts - 02-04-2019

No way. What are you trying to achieve?


RE: Add new paint method ? - Jack Parker - 02-05-2019

Thanks for the confirmation.

I *was* going to make a procedural pass along the path, removing/repainting the pixels that are obviously "scanner-noise"
(nearly black or nearly white pixels on the edge that do not match (within threshhold) the pixels that are 5 pixels "in" from the edge)

I have scanned some images, and there are edge pixels that are black (where scan exceeds the card width) or white (where scan light causes highlight)
cannot simply remove all the outer black because some of the graphics have black that extends to the edge...
Can do some of it with select-contiguous color, but for the fine-points, a procedural brush would have been elegant.
[by now i see that the scheme API cannot even read the color value at a pixel...
nor does it expose the "color distance" calculation, so yeah: not going to happen]

I have since decided to work-around by masking off the areas where the graphic are known to reach the edge.
(and then can use selection-border and just fill the un-masked area with the know/assumed color)
It is not as "perfect", and needed to be tuned for the 6 card types, but it will suffice.

Now i need to find the gimp or script-fu equivalent of scheme's string-index function...
(so i can read the card-type from the filename, and use the correct mask values)

I've seen you ask in other posts: It's because I'm a Lisp programmer from *way* back.

Found this: (car (strbreakup orig-name "."))
[thank you, stackoverflow]

Is there a list of all the script-fu functions?
(the "browser" finds all the gimp-* functions, but all the others that are in *this* version of scheme/tinyscheme?


RE: Add new paint method ? - Ofnuts - 02-05-2019

(02-05-2019, 06:59 AM)Jack Parker Wrote: [by now i see that the scheme API cannot even read the color value at a pixel...

You overlooked gimp-drawable-get-pixel. However scripts that read pixel by pixel are awfully slow. In python you can access the pixels as arrays, so things are a lot faster.

To smooth the edges you can do a "Select-by-color", then Select>To path, and then Select>From path and bucket fill the result on another layer. And if you are script-prone you can also tweak the path with a script between the two Select operations, and for instance discard points that create local sharp edges, etc... (see the *vector* functions). I can show you plenty of example code for this, but all in Python Smile


RE: Add new paint method ? - Jack Parker - 02-05-2019

Thanks for the suggestions.
I'll see if that approach improves on the gimp-image-selection-border + drawable-fill (is that a "bucket fill"?)

Always happy to see example code, even in python;
so see how the parts/components are best used.
especially if the function names are mappable...


RE: Add new paint method ? - Ofnuts - 02-05-2019

IIRC gimp-drawable-fill is meant to fill a full drawable (some way to initialize it). You want gimp-edit-bucket-fill.

See here for set of path-related scripts. All the pdb.* functions have direct equivalents in the script-fu API. Object methods are also a fairly direct mapping to PDB functions and hence to the script-fu API.


RE: Add new paint method ? - Jack Parker - 02-05-2019

Ok, thanks... Where are the *.pdb functions listed?

Does that include non-graphic functions?

For ex: what is the script-fu/tinyscheme replacement for (princ)  or (prin1) or other way to make a string from a object?


RE: Add new paint method ? - Jack Parker - 02-06-2019

Indeed, I mis-spoke I'm using gimp-drawable-edit-fill (but wrapped in a function so i forgot the detailed spelling)

Found "schemers.org" which has posted the R5RS, to which tinyscheme is an approximation.

For the record, here is an tinyscheme/script-fu implementation of ~ prin1
suitable for (gimp-message (stringify obj)) if you want to see intermediate results

I'm not set up to put it in a git or sourceforge repo, but feel free to copy and use.

Unlike the REPL, this does not hang on recursive structure, but truncates to the first ~200 chars
(more or less if you supply a second arg)

For example:
> (load ".../GIMP/2.10/scripts/stringify.scm")
stringify#<EOF>#t
> (define x '(1 2 3 replace-me-with-x)))
x
> (stringify x)
"(1 2 3 'replace-me-with-x)"
> (stringify (set-cdr! (cddr x) x))
"(3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 ..."
> (stringify (set-cdr! (cddr x) x) 30)
"(3 1 2 3 1 2 3 1 2 3 1 2 3 1 ..."

;; stringify.scm
;; return a string rendition of a lisp object.
;; [better than] what the top-level REPL does, now available for use.
;;
;; suitable for gimp-message if you want to see intermediate results
;; creates a readable string, compare to "prin1"
;;
;; License: Free Open Source, copy, modify and use as you wish.
;; No warranty expressed or implied, use at your own risk.

(define (stringify obj . args)                  ; returns String
  (define max_size 0)
  (define buffer ())                    ;use cons and reverse...
  (define size 0)

  (define (buffer-add str) (set! buffer (cons str buffer)))
    
  (define (buffer->string)
    (if (>= size max_size)
        (buffer-add "..."))
    (let* ((buf (reverse buffer)))
      (apply string-append buf)))


  (define (buffer-append str)
    (if (string? str) ; when full, pair->string may return nil
        (begin
          (set! size (+ size (string-length str)))
          (if (< size max_size)
              (buffer-add str)
              ))))
           
  (define (obj->string obj nullstr)             ;return string
    (cond ((null? obj) nullstr)
          ((symbol? obj) (string-append "'" (symbol->string obj)))
          ((string? obj) (string-append "\"" obj "\""))
          ((number? obj) (number->string obj))
          ((vector? obj) (vector->string obj))
          ((pair?   obj) (pair->string obj))
          (#t "???")
          )
    )

  (define (pair->string obj) ; return (tail->string ...) ==> ")"
    (if (< size max_size)
        (begin
          (buffer-append "(")
          (buffer-append (obj->string (car obj) "nil")) ; or "()"
          (tail->string (cdr obj))
          )
        )
    )

  (define (tail->string obj) ;; return ")"
    (if (< size max_size)
        (begin
          (cond
           ((pair? obj)
            (buffer-append " ")
            (buffer-append (obj->string (car obj) "nil" ))
            (tail->string (cdr obj))
            )
           ((null? obj))
           (#t 
            (buffer-append " . ")
            (buffer-append (obj->string obj ""))
            ))
          ")")
        )
    )

  (define (vector->string obj)
    ;; left as an exercise for the motivated reader
    (if (< size max_size)
        (let ((len (vector-length obj)))
          (buffer-append 
           (string-append "[vector: " (number->string len) "]")))
        )
    )

  (set! max_size (if (and (pair? args) (number? (car args))) (car args) 200))
  (buffer-append (obj->string obj "()"))
  (buffer->string)
  
  )



RE: Add new paint method ? - Ofnuts - 02-06-2019

(02-06-2019, 03:45 AM)Jack Parker Wrote: Indeed, I mis-spoke I'm using gimp-drawable-edit-fill (but wrapped in a function so i forgot the detailed spelling)

Found "schemers.org" which has posted the R5RS, to which tinyscheme is an approximation.

For the record, here is an tinyscheme/script-fu implementation of ~ prin1
suitable for (gimp-message (stringify obj)) if you want to see intermediate results

I'm not set up to put it in a git or sourceforge repo, but feel free to copy and use.

Unlike the REPL, this does not hang on recursive structure, but truncates to the first ~200 chars
(more or less if you supply a second arg)

For example:
> (load ".../GIMP/2.10/scripts/stringify.scm")
stringify#<EOF>#t
> (define x '(1 2 3 replace-me-with-x)))
x
> (stringify x)
"(1 2 3 'replace-me-with-x)"
> (stringify (set-cdr! (cddr x) x))
"(3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 ..."
> (stringify (set-cdr! (cddr x) x) 30)
"(3 1 2 3 1 2 3 1 2 3 1 2 3 1 ..."

;; stringify.scm
;; return a string rendition of a lisp object.
;; [better than] what the top-level REPL does, now available for use.
;;
;; suitable for gimp-message if you want to see intermediate results
;; creates a readable string, compare to "prin1"
;;
;; License: Free Open Source, copy, modify and use as you wish.
;; No warranty expressed or implied, use at your own risk.

(define (stringify obj . args)                  ; returns String
  (define max_size 0)
  (define buffer ())                    ;use cons and reverse...
  (define size 0)

  (define (buffer-add str) (set! buffer (cons str buffer)))
    
  (define (buffer->string)
    (if (>= size max_size)
        (buffer-add "..."))
    (let* ((buf (reverse buffer)))
      (apply string-append buf)))


  (define (buffer-append str)
    (if (string? str) ; when full, pair->string may return nil
        (begin
          (set! size (+ size (string-length str)))
          (if (< size max_size)
              (buffer-add str)
              ))))
           
  (define (obj->string obj nullstr)             ;return string
    (cond ((null? obj) nullstr)
          ((symbol? obj) (string-append "'" (symbol->string obj)))
          ((string? obj) (string-append "\"" obj "\""))
          ((number? obj) (number->string obj))
          ((vector? obj) (vector->string obj))
          ((pair?   obj) (pair->string obj))
          (#t "???")
          )
    )

  (define (pair->string obj) ; return (tail->string ...) ==> ")"
    (if (< size max_size)
        (begin
          (buffer-append "(")
          (buffer-append (obj->string (car obj) "nil")) ; or "()"
          (tail->string (cdr obj))
          )
        )
    )

  (define (tail->string obj) ;; return ")"
    (if (< size max_size)
        (begin
          (cond
           ((pair? obj)
            (buffer-append " ")
            (buffer-append (obj->string (car obj) "nil" ))
            (tail->string (cdr obj))
            )
           ((null? obj))
           (#t 
            (buffer-append " . ")
            (buffer-append (obj->string obj ""))
            ))
          ")")
        )
    )

  (define (vector->string obj)
    ;; left as an exercise for the motivated reader
    (if (< size max_size)
        (let ((len (vector-length obj)))
          (buffer-append 
           (string-append "[vector: " (number->string len) "]")))
        )
    )

  (set! max_size (if (and (pair? args) (number? (car args))) (car args) 200))
  (buffer-append (obj->string obj "()"))
  (buffer->string)
  
  )

Can't help notice that all this looks like built-in Python functionality. Of course, there is almost half a century between Lisp and Python Smile


RE: Add new paint method ? - Jack Parker - 02-06-2019

FWIW: I can't prove it is *not* built-in to script-fu/tinyscheme

but I can't find a list of the implemented functions (beyond the pda.*)