I have an interesting case where I have a circular logo which I
overlay on a web-page.  The logo needs to have a transparent
background, however it is placed over many different elements (the
background is not a solid color), so I can't use the smei-flatten code
to antialias it.

Originally, we had just used flash for the logo, but not all browsers
support transparency in flash, so I converted it to a gif (and lost
the nice smooth edges)

My solution was to import an image of the webpage (without the logo)
as a second layer, and do a 'smart' semi-flatten between the
transparent logo layer and the background image).  This results in
antialiasing against any background (doesn't need to be a solid color)
as long as it isn't dynamic.

Since I did this in Windows, and didn't want to compile everything, I
wrote it in Script-Fu.

Below is the code if someone finds it useful (Since it is doing
pixel-by-pixel checks, it is very slow, and should really be in C, but
it works for my needs).  Also, while I am familiar with lisp, this is
my first attempt at Script-Fu, so the code is pretty cludgy)

;; -*-scheme-*-
;; This script will apply semi-flatten against a background layer
;; instead of just a solid color

(define (script-fu-smart-semiflattern image drawable fg bkgnd)
 (gimp-image-undo-disable image)
 (if (or (or (= fg -1) (= bkgnd -1)) (= fg bkgnd)) t
 (let ()
 (set! drawable fg)
 (set! width (car (gimp-drawable-width drawable)))
 (set! height (car (gimp-drawable-height drawable)))
 (set! y 0)
 (while (< y height)
   (gimp-progress-update (/ y height))
   (set! x 0)
   (while (< x width)
     (set! pxll (gimp-drawable-get-pixel drawable x y))
     (set! pxl (cadr pxll))
     (set! alpha (aref pxl 3))
     (if (or (= alpha 0) (= alpha -1)) t
        (let ()
           ;(print "alpha: ")
           ;(print x)
           ;(print y)
           ;(print alpha)
           (set! bgpxl (cadr (gimp-drawable-get-pixel bkgnd x y)))
           (set! a (aref pxl 3)) (if (< a 0) (set! a (+ 256 a)))
           (set! r (aref pxl 0)) (if (< r 0) (set! r (+ 256 r)))
           (set! rb (aref bgpxl 0)) (if (< rb 0) (set! rb (+ 256 rb)))
           (set! g (aref pxl 1)) (if (< g 0) (set! g (+ 256 g)))
           (set! gb (aref bgpxl 1)) (if (< gb 0) (set! gb (+ 256 gb)))
           (set! b (aref pxl 2)) (if (< b 0) (set! b (+ 256 b)))
           (set! bb (aref bgpxl 2)) (if (< bb 0) (set! bb (+ 256 bb)))
           (aset pxl 0 (/ (+ (* a r) (* (- 255 a) rb)) 255))
           (aset pxl 1 (/ (+ (* a g) (* (- 255 a) gb)) 255))
           (aset pxl 2 (/ (+ (* a b) (* (- 255 a) bb)) 255))
           (aset pxl 3 255)
           (gimp-drawable-set-pixel drawable x y (car pxll) pxl)
     (set! x (+ x 1))
   (set! y (+ y 1))
 (gimp-image-undo-enable image)

(script-fu-register "script-fu-smart-semiflatten"
                   _"_Smart Semi-Flatten"
                   "Semi flatten against a background image."
                   "Geoffrey Hausheer"
                   "Geoffrey Hausheer, 2005. Public Domain."
                   "January 2005"
                   SF-IMAGE    "Image"    0
                   SF-DRAWABLE "Drawable" 0
                   SF-LAYER    "Foreground Layer" -1
                   SF-LAYER    "Background Layer" -1

(script-fu-menu-register "script-fu-smart-semiflatten"
Gimp-user mailing list

Reply via email to