Antialiasing transparent gifs against a background image
This discussion is connected to the gimp-user-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.
This is a read-only list on gimpusers.com so this discussion thread is read-only, too.
Antialiasing transparent gifs against a background image | Geoffrey Hausheer | 29 Jan 23:27 |
Antialiasing transparent gifs against a background image
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)
.Geoff
--------------------------------------------------------
;; -*-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)
(gimp-displays-flush)
)
(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" "/Script-Fu/Colors")