From mike at sharedlogic.ca Tue Sep 11 16:13:24 2007 From: mike at sharedlogic.ca (Michael J. Forster) Date: Tue, 11 Sep 2007 11:13:24 -0500 Subject: [cl-gd-devel] with-transformation off-by-one bug? Message-ID: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> Hi Edi, I'm using CL-GD with both LispWorks 5.0 on OS X and CMUCL 19b on FreeBSD to plot some graphs, and I'm very grateful for your work here. CL-GD is slick to use and more than fast enough for generating sparklines on an interactive web-based dashboard. I'm using WITH-TRANSFORMATION to simplify the graph plotting, and it's not behaving the way I would expect. As I read it in the documentation, this... (with-transformation (:x1 0 :width width :y1 0 :height height) ...) ... should transform the coordinate system from this... 0,0 -----> width - 1 | | | V height - 1 ... to this... height - 1 ^ | | | 0,0 -----> width - 1 Instead, I get this... height ^ | | | 0,1 -----> width - 1 The y-axis transformation isn't consistent with that of the x-axis. What's even more confusing, is that if the x-axis transformation does work then the following should only complain about y1, y2, and height, and not about x1, x2, and width, but that's not the case: (let ((height 100) (width 100)) (with-transformation (:x1 0 :x2 (1- width) :width width :y1 0 :y2 (1- height) :height height) ...)) Indeed, when I checked the macroexpansion, I see... (UNLESS #:X154021 (SETQ #:X154021 (- #:X254022 #:WIDTH54023))) (UNLESS #:X254022 (SETQ #:X254022 (+ #:X154021 #:WIDTH54023))) (UNLESS #:WIDTH54023 (SETQ #:WIDTH54023 (- #:X254022 #:X154021))) (UNLESS #:Y154024 (SETQ #:Y154024 (- #:Y254025 #:HEIGHT54026))) (UNLESS #:Y254025 (SETQ #:Y254025 (+ #:Y154024 #:HEIGHT54026))) (UNLESS #:HEIGHT54026 (SETQ #:HEIGHT54026 (- #:Y254025 #:Y154024))) Again, I would have thought, instead, that... width = (x2 - x1) + 1 height = (y2 - y1) + 1 So, the y-axis transformation isn't what I expected, but the macroexpansion suggests that the x-axis transformation should be off by one as well, yet it isn't. Am I nuts? Below is the snippet I was running to grok WITH-TRANSFORMATION. I can mail you the images I got, if you like. Thanks in advance, Mike (let* ((height 100) (width 100) (origin+1 (list 1 1)) (x-axis+1 (list 10 1 20 1 30 1 40 1 50 1 60 1 70 1 80 1 90 1 width 1)) (y-axis+1 (list 1 10 1 20 1 30 1 40 1 50 1 60 1 70 1 80 1 90 1 height)) (x-axis-end+1 (list (1- width) 1)) (y-axis-end+1 (list 1 (1- height)))) (cl-gd:with-image* (width height) (allocate-color 255 255 255) (let ((black (allocate-color 0 0 0)) (red (allocate-color 255 0 0)) (green (allocate-color 0 255 0)) (blue (allocate-color 0 0 255)) (yellow (allocate-color 255 255 0))) (draw-rectangle* 0 (1- height) ; or 0 and ... (1- width) 0 ; (1- height), doesn't matter :color yellow) (draw-rectangle* 0 height ; or 0 and ... width 0 ; ... height, doesn't matter :color black) (set-pixels origin+1 :color red) (set-pixels x-axis+1 :color green) (set-pixels x-axis-end+1 :color blue) (set-pixels y-axis+1 :color green) (set-pixels y-axis-end+1 :color blue)) (write-image-to-file "/tmp/test1.png" :if-exists :supersede)) (cl-gd:with-image* (width height) (allocate-color 255 255 255) (let ((black (allocate-color 0 0 0)) (red (allocate-color 255 0 0)) (green (allocate-color 0 255 0)) (blue (allocate-color 0 0 255)) (yellow (allocate-color 255 255 0))) (with-transformation (:x1 0 ;;:x2 99 :width width :y1 0 ;;:y2 99 :height height ) (draw-rectangle* 0 (1- height) ; or 0 and ... (1- width) 0 ; (1- height), doesn't matter :color yellow) (draw-rectangle* 0 height ; or 0 and ... width 0 ; ... height, doesn't matter :color black) (set-pixels origin+1 :color red) (set-pixels x-axis+1 :color green) (set-pixels x-axis-end+1 :color blue) (set-pixels y-axis+1 :color green) (set-pixels y-axis-end+1 :color blue)) (write-image-to-file "/tmp/test2.png" :if-exists :supersede)))) -- Michael J. Forster From edi at agharta.de Thu Sep 13 09:14:46 2007 From: edi at agharta.de (Edi Weitz) Date: Thu, 13 Sep 2007 11:14:46 +0200 Subject: [cl-gd-devel] with-transformation off-by-one bug? In-Reply-To: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> (Michael J. Forster's message of "Tue, 11 Sep 2007 11:13:24 -0500") References: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> Message-ID: On Tue, 11 Sep 2007 11:13:24 -0500, "Michael J. Forster" wrote: > I'm using WITH-TRANSFORMATION to simplify the graph plotting, and > it's not behaving the way I would expect. As I read it in the > documentation, this... > > (with-transformation (:x1 0 > :width width > :y1 0 > :height height) > ...) > > > ... should transform the coordinate system from this... > > 0,0 -----> width - 1 > | > | > | > V > height - 1 > > ... to this... > > height - 1 > ^ > | > | > | > 0,0 -----> width - 1 Hmm, why do you think that? I would expect a transformation from 0,0 -----> image-width | | | V image-height to height ^ | | | 0,0 -----> width Why do you want to subtract 1? What do you expect to happen if WIDTH or HEIGHT /are/ 1? > Below is the snippet I was running to grok WITH-TRANSFORMATION. I > can mail you the images I got, if you like. An easy way to experiment with CL-GD's transformations would probably be something like this: (in-package :cl-gd) (defun foo (x1 y1 x2 y2 &optional (image *default-image*)) (with-transformed-alternative ((x1 x-transformer) (y1 y-transformer) (x2 x-transformer) (y2 y-transformer)) (print (list x1 y1 x2 y2)))) (with-image* (... ...) (with-transformation (:x1 ... :width ... :y1 ... :height ...) (foo ... ... ... ...))) Cheers, Edi. From mike at sharedlogic.ca Thu Sep 13 13:29:56 2007 From: mike at sharedlogic.ca (Michael J. Forster) Date: Thu, 13 Sep 2007 08:29:56 -0500 Subject: [cl-gd-devel] with-transformation off-by-one bug? In-Reply-To: References: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> Message-ID: <3A28F379-6357-4BA8-99EC-414401AEA66F@sharedlogic.ca> On 13-Sep-07, at 4:14 AM, Edi Weitz wrote: > On Tue, 11 Sep 2007 11:13:24 -0500, "Michael J. Forster" > wrote: > >> I'm using WITH-TRANSFORMATION to simplify the graph plotting, and >> it's not behaving the way I would expect. As I read it in the >> documentation, this... >> >> (with-transformation (:x1 0 >> :width width >> :y1 0 >> :height height) >> ...) >> >> >> ... should transform the coordinate system from this... >> >> 0,0 -----> width - 1 >> | >> | >> | >> V >> height - 1 >> >> ... to this... >> >> height - 1 >> ^ >> | >> | >> | >> 0,0 -----> width - 1 > > Hmm, why do you think that? I would expect a transformation from > > 0,0 -----> image-width > | > | > | > V > image-height > > to > > height > ^ > | > | > | > 0,0 -----> width > > Why do you want to subtract 1? What do you expect to happen if WIDTH > or HEIGHT /are/ 1? I was thinking of lines on a graph as zero-based vectors. Thus, a vector of length (or axis of width or height) n is indexed from 0 to n-1. And, indeed, with the following... (let ((height 100) (width 100) (x-axis-width (list width 1)) (y-axis-height (list 1 height)) (x-axis-width-1 (list (1- width) 1)) (y-axis-height-1 (list 1 (1- height)))) (cl-gd:with-image* (width height) (set-pixels x-axis-width) (set-pixels y-axis-height) (set-pixels x-axis-width-1) (set-pixels y-axis-height-1) ...)) ... only the last two pixels are displayed on my 100x100 pixel image. The axes are indexed from 0 to n-1. If WIDTH and HEIGHT are 1, I only expect to see the pixel generated by... (set-pixels '(0 0)) Is my brain off by one? Thanks and best regards, Mike -- Michael J. Forster From edi at agharta.de Fri Sep 14 07:19:44 2007 From: edi at agharta.de (Edi Weitz) Date: Fri, 14 Sep 2007 09:19:44 +0200 Subject: [cl-gd-devel] with-transformation off-by-one bug? In-Reply-To: <3A28F379-6357-4BA8-99EC-414401AEA66F@sharedlogic.ca> (Michael J. Forster's message of "Thu, 13 Sep 2007 08:29:56 -0500") References: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> <3A28F379-6357-4BA8-99EC-414401AEA66F@sharedlogic.ca> Message-ID: On Thu, 13 Sep 2007 08:29:56 -0500, "Michael J. Forster" wrote: > I was thinking of lines on a graph as zero-based vectors. Thus, a > vector of length (or axis of width or height) n is indexed from 0 to > n-1. And, indeed, with the following... > > (let ((height 100) > (width 100) > (x-axis-width (list width 1)) > (y-axis-height (list 1 height)) > (x-axis-width-1 (list (1- width) 1)) > (y-axis-height-1 (list 1 (1- height)))) > (cl-gd:with-image* (width height) > (set-pixels x-axis-width) > (set-pixels y-axis-height) > (set-pixels x-axis-width-1) > (set-pixels y-axis-height-1) > ...)) > > ... only the last two pixels are displayed on my 100x100 pixel > image. The axes are indexed from 0 to n-1. If WIDTH and HEIGHT are > 1, I only expect to see the pixel generated by... > > (set-pixels '(0 0)) I think where CL-GD and you disagree is that currently the outermost "virtual" point (X2 or (+ X1 WIDTH)) is mapped to the first point which is /not/ on the real image (and similar for the other axis), i.e. the transformation arguments kind of describe a half-open interval. I can see how this is inconvenient and I wouldn't mind changing that unless someone else provides important reasons not to do it. Could you please check if the attached patch does what you want? As for your complaints about the x-axis transformation not being consistent with the y-axis transformation, are you sure you're not seeing rounding errors? Or maybe this happened because of the "one off" stuff plus the fact that the "virtual" y-axis usually points into the opposite direction? Cheers, Edi. -------------- next part -------------- A non-text attachment was scrubbed... Name: transform.diff Type: text/x-patch Size: 663 bytes Desc: not available URL: From mike at sharedlogic.ca Fri Sep 14 10:17:16 2007 From: mike at sharedlogic.ca (Michael J. Forster) Date: Fri, 14 Sep 2007 05:17:16 -0500 Subject: [cl-gd-devel] with-transformation off-by-one bug? In-Reply-To: References: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> <3A28F379-6357-4BA8-99EC-414401AEA66F@sharedlogic.ca> Message-ID: On 14-Sep-07, at 2:19 AM, Edi Weitz wrote: > On Thu, 13 Sep 2007 08:29:56 -0500, "Michael J. Forster" > wrote: > >> I was thinking of lines on a graph as zero-based vectors. Thus, a >> vector of length (or axis of width or height) n is indexed from 0 to >> n-1. And, indeed, with the following... >> >> (let ((height 100) >> (width 100) >> (x-axis-width (list width 1)) >> (y-axis-height (list 1 height)) >> (x-axis-width-1 (list (1- width) 1)) >> (y-axis-height-1 (list 1 (1- height)))) >> (cl-gd:with-image* (width height) >> (set-pixels x-axis-width) >> (set-pixels y-axis-height) >> (set-pixels x-axis-width-1) >> (set-pixels y-axis-height-1) >> ...)) >> >> ... only the last two pixels are displayed on my 100x100 pixel >> image. The axes are indexed from 0 to n-1. If WIDTH and HEIGHT are >> 1, I only expect to see the pixel generated by... >> >> (set-pixels '(0 0)) > > I think where CL-GD and you disagree is that currently the outermost > "virtual" point (X2 or (+ X1 WIDTH)) is mapped to the first point > which is /not/ on the real image (and similar for the other axis), > i.e. the transformation arguments kind of describe a half-open > interval. I can see how this is inconvenient and I wouldn't mind > changing that unless someone else provides important reasons not to do > it. Could you please check if the attached patch does what you want? > > As for your complaints about the x-axis transformation not being > consistent with the y-axis transformation, are you sure you're not > seeing rounding errors? Or maybe this happened because of the "one > off" stuff plus the fact that the "virtual" y-axis usually points into > the opposite direction? > Hi Edi, Thanks for getting back to me so quickly. I will be away on business for a couple of days, so if you'll let me ponder your comments and play with the patch, I'll get back to you early next week. And I hope you didn't take any of this as a complaint. It's really a matter of me wrapping my brain around CL-GD's behaviour in these corner cases (no pun intended). Regardless, WITH-TRANSFORMATION is much nicer than the translation and scaling hacks required to use, say, PHP's GD bindings. Thanks again, Mike -- Michael J. Forster From edi at agharta.de Fri Sep 14 11:59:17 2007 From: edi at agharta.de (Edi Weitz) Date: Fri, 14 Sep 2007 13:59:17 +0200 Subject: [cl-gd-devel] with-transformation off-by-one bug? In-Reply-To: (Michael J. Forster's message of "Fri, 14 Sep 2007 05:17:16 -0500") References: <29C2A817-3C39-4CBF-A18D-33B095D9E2AF@sharedlogic.ca> <3A28F379-6357-4BA8-99EC-414401AEA66F@sharedlogic.ca> Message-ID: On Fri, 14 Sep 2007 05:17:16 -0500, "Michael J. Forster" wrote: > Thanks for getting back to me so quickly. I will be away on > business for a couple of days, so if you'll let me ponder your > comments and play with the patch, I'll get back to you early next > week. OK, no problem. > And I hope you didn't take any of this as a complaint. Nah, that's OK. My reaction basically showed that I myself never used these transformations in earnest... :) From yazicivo at ttnet.net.tr Sun Sep 23 17:31:10 2007 From: yazicivo at ttnet.net.tr (Volkan YAZICI) Date: Sun, 23 Sep 2007 20:31:10 +0300 Subject: [cl-gd-devel] Resizing Images Message-ID: <87ejgpl25d.fsf@ttnet.net.tr> Hi, While trying to resize images, using COPY-IMAGE, there occurs serious color losses. Here is an example code snippet to re-produce the problem: (cl-gd:with-image-from-file (src "/tmp/src.jpg" :jpeg) (let* ((src-w (cl-gd:image-width src)) (src-h (cl-gd:image-height src)) (dst-w (truncate (/ src-w 2))) ; WIDTH /2 (dst-h (truncate (/ src-h 2)))) ; HEIGHT/2 (cl-gd:with-image (dst dst-w dst-h) ;; Set transparent color, if any. (let ((transparent-color (cl-gd:transparent-color src))) (if transparent-color (destructuring-bind (red green blue alpha) (cl-gd:color-components transparent-color :image src) (setf (cl-gd:transparent-color dst) (cl-gd:allocate-color red green blue :alpha alpha :image dst))))) ;; Copy source scaled onto the destination. (cl-gd:copy-image src dst 0 0 0 0 (cl-gd:image-width src) (cl-gd:image-height src) :resample t :resize t :dest-width dst-w :dest-height dst-h) ;; Output result. (cl-gd:write-image-to-file "/tmp/dst.jpg" :type :jpeg :image dst :if-exists :supersede)))) Can anybody spot the problem in the above code? (Removing the part that sets the transparent color doesn't make any difference.) How do you resize images in cl-gd? Regards. From edi at agharta.de Sun Sep 23 18:47:45 2007 From: edi at agharta.de (Edi Weitz) Date: Sun, 23 Sep 2007 20:47:45 +0200 Subject: [cl-gd-devel] Resizing Images In-Reply-To: <87ejgpl25d.fsf@ttnet.net.tr> (Volkan YAZICI's message of "Sun, 23 Sep 2007 20:31:10 +0300") References: <87ejgpl25d.fsf@ttnet.net.tr> Message-ID: On Sun, 23 Sep 2007 20:31:10 +0300, Volkan YAZICI wrote: > Can anybody spot the problem in the above code? (Removing the part > that sets the transparent color doesn't make any difference.) How do > you resize images in cl-gd? Did you try the equivalent in C? It might be a problem in GD itself and not in CL-GD. From yazicivo at ttnet.net.tr Sun Sep 23 20:26:57 2007 From: yazicivo at ttnet.net.tr (Volkan YAZICI) Date: Sun, 23 Sep 2007 23:26:57 +0300 Subject: [cl-gd-devel] Re: Resizing Images In-Reply-To: (Edi Weitz's message of "Sun\, 23 Sep 2007 20\:47\:45 +0200") References: <87ejgpl25d.fsf@ttnet.net.tr> Message-ID: <87abrdku0e.fsf_-_@ttnet.net.tr> Edi Weitz writes: > On Sun, 23 Sep 2007 20:31:10 +0300, Volkan YAZICI wrote: >> Can anybody spot the problem in the above code? (Removing the part >> that sets the transparent color doesn't make any difference.) How do >> you resize images in cl-gd? > > Did you try the equivalent in C? It might be a problem in GD itself > and not in CL-GD. Umm... Also libgd provides identical output. (Code is attached.) Seems like I'm missing something. Any ideas? How do you resize your images? Regards. -------------- next part -------------- A non-text attachment was scrubbed... Name: libgd-resize.c Type: text/x-csrc Size: 854 bytes Desc: not available URL: From yazicivo at ttnet.net.tr Sun Sep 23 20:42:45 2007 From: yazicivo at ttnet.net.tr (Volkan YAZICI) Date: Sun, 23 Sep 2007 23:42:45 +0300 Subject: [cl-gd-devel] Re: Resizing Images In-Reply-To: <87abrdku0e.fsf_-_@ttnet.net.tr> (Volkan YAZICI's message of "Sun\, 23 Sep 2007 23\:26\:57 +0300") References: <87ejgpl25d.fsf@ttnet.net.tr> <87abrdku0e.fsf_-_@ttnet.net.tr> Message-ID: <876421kta2.fsf_-_@ttnet.net.tr> Volkan YAZICI writes: > ... > dsth = (unsigned int) (scale * srch); > dstip = gdImageCreate(dstw, dsth); Replacing gdImageCreate() with gdImageCreateTrueColor() solved the problem. (A similar approach is applicable for :TRUE-COLOR key of WITH-IMAGE macro as well.) Regards.