GD is an open source code library for the dynamic creation of images by programmers. GD is written in C, and “wrappers” are available for Perl, PHP and other languages. GD creates PNG, JPEG and GIF images, among other formats. GD is commonly used to generate charts, graphics, thumbnails, and most anything else, on the fly. While not restricted to use on the web, the most common applications of GD involve web site development.
See the GD website for more informations.
FS#79 — arc's are drawn incorrectly (plus regression in 2.0.35RC2)
Opened by Colen Garoutte-Carson (Colen) - Friday, 04 May 2007, 09:15 GMT+2
Last edited by Pierre Joye (Pierre) - Thursday, 21 June 2007, 21:39 GMT+2
|
DetailsI recently upgraded from 2.0.33 to 2.0.35RC2, to see if some bugs I’ve encountered had been fixed, before reporting them. I noticed a regression in how arc’s are drawn. See the attached images. The left side of the circle generated by 2.0.35RC2 looks corrupted. Since the algorithm should be equivilent in all 4 quadrants, hopefully it’s just a minor math error translating between quandrants. Another (existing) issue I’ve encountered is that arcs of any significant thickness do not draw correctly. I’ve attached the same circles at a thickness of 50 (though the problem is noticable at a thickness of 3). Neither looks much like a circle. - Colen |
circle_1_gd2.0.33.gif
Hi,
Thanks for your feedback!
The gdImageArc implementation did not change, however I suspect another bug to be the cause of this problem: #77 (http://bugs.libgd.org/?do=details&task_id=77)
vertical lines were not drawn correclty anymore, this regression was introduced after a fix in the anti anti aliased line function (axis aligned lines were two pixels wide).
Please try your code using the CVS version (I will release a RC3 during the weekend). I will also add new test cases regarding the arc functions.
About the thickness problem, it is a general problem with many shapes. I’m working on a solution for gd 2.1.0. See the following samples: http://blog.thepimp.net/misc/ellipsethick.html (ellipse with thickness > 1 and transparency) or http://pierre.libgd.org/polygons/ (general shapes antialiasing, incl. transparency support)
I'm trying to install the CVS version, but am getting:
...on RH Linux ES4. I installed the latest version of autoconf, but this still repros. Do I need to upgrade or downgrade something?
Thanks, - Colen
You may need a more recent autoconf version. I know automake 1.9 is required, I'm not sure about the minimum version of autoconf. I use 2.61.
You can setup it in a separate directory and override the default using:
for example. AUTOCONF, ACLOCAL, AUTOHEADER and AUTOMAKE can be set.
I forgot to mention the branch to use. Please use GD_2_0 (cvs -r GD_20...)
I forgot to mention the branch to use. Please use GD_2_0 (cvs -r GD_2_0...)
I have autoconf 2.61 and automake 1.9.6 installed. I tried automake 1.9, as you suggested. I also tried with and without "-r GD_2_0". In each case, I got the same output from bootstrap.sh . Example is attached. I appologize if this is due to an issue on my system. (Unix is not my native platform.) But, it sounds like you have solutions for both arc issues. I look forward to version 2.1. :)
I uploaded 2.0.35RC3, it may help you to test the last changes.
You can find it here: http://www.libgd.org/releases/
Please let me know if it works as expected (except the thickness problem, that's another issue for 2.1.0)
I was able to fix my config problem. I needed to update libtool.
2.0.35RC3 seems to address the problem for gif and jpeg, but I am seeing a problem with anti-aliased lines and arcs in PNG TrueColor images.
... generates the attached image. Similar artifacts are there, and the thickness is not correct. The problem does not happen if gdAntiAliased is not used.
- Colen
Ok, the antialias multiple blending ends with a horrible result in gdImageArc and without any antialiasing effect (still jaggy anyway).
The attached patch fixes the issue. I think it is a good way to solve the problem without loosing the actual fix in gdImageAALine for axis aligned lines.
The previous versions did not draw arcs pixels using only black. I think it is an acceptable change given that it never works well anyway. Is it good enough in your case?
I am seeing the problem with AA lines as well. AA lines at certain angles(?) are not drawn in true-color PNG. (Attached is a circle drawn using lines.) I'd like to use PNG output to support alpha anti-aliased text, which works well. Is there a existing solution for drawing smooth/AA diagonal lines in true-color PNG?
- Colen
It is not a problem of the AA lines but the way we draw circles, ellipses (arc or full). We draw arcs using many lines. Extrems of the arc are drawn using single pixel lines mostl. Many of them overlap, blending ops are done many times within the same area. It ends to pure white when the drawing operation is finished.
You can draw AA lines at any angle, it works. But if you draw again again on the same area, the result will likely look like the background color.
A better approach to draw circles or ellipses is to use the Bresenham algorithm. I use it in my new implementation of the gdImageFilledEllipse function (already in 2.0.34 and later). That's what I use as well in the upcoming antialiased arcs functions.
What's about this change, does it work as you expect? (without AA, it cannot be done in 2.0.x but in 2.1.x).
I made a mistake in my comment. Your image is relatively very large and reduce the effect I was trying to describe. There is (bad) regression here. A fix will be present in 2.0.35 (meaning a RC4, damned :).
Thanks for your patience!
Fixed in GD_2_0 and HEAD. It should work as you expect now. The fix will be in 2.0.35.
Cool. :) To clarify, "test.png" was not drawn using arcs. I drew that circle with lines, by rotating individual points and connecting them.
- Colen
"Cool. :) To clarify, "test.png" was not drawn using arcs. I drew that circle with lines, by rotating individual points and connecting them."
Yes, I saw it afterwards, we use a similar implementation in the current arc function.
Only to be sure that everything works well, can you try again using CVS (GD_2_0 or head) please?
There are still problems with the latest from CVS. Diagonal lines use incorrect width and are antialiased against the wrong color (black instead of transparent?).
Attached is the same circle made w/lines, at thickness of 6, anti-aliased against transparent (0,0,0,127).
The same drawing operations look correct when not using truecolor png, or when saveAlpha is 0.
- Colen
"There are still problems with the latest from CVS. Diagonal lines use incorrect width and are antialiased against the wrong color (black instead of transparent?)."
Do you mean when the thickness > 1? Antialiased lines do not support thickness > 1, it is always 1. If not and if the wrong color still appears, do you have a sample code and result (only the line)? I cannot reproduce the problem here. 45° line are not really antialiased are they are pixel aligned, each point of the lines cover a complete pixel (end points are always on a pixel):
[X] [X] [X]Maybe it is what you are seeing?
"Attached is the same circle made w/lines, at thickness of 6, anti-aliased against transparent (0,0,0,127). The same drawing operations look correct when not using truecolor png, or when saveAlpha is 0. "
Thickness does not work, it will only work correctly in 2.1.0. When the thickness>1, it will draws many times the same spans (blending over and over the same pixels).
Am I right to think that it actually works for you now (like with 2.0.33)? :)
The improvements (thickness>1 and transparency) will be done later, in the 2.1.x branch.
$im = new GD::Image($width, $height, 1); $im->alphaBlending(0); $im->saveAlpha(1); $transparent = $im->colorAllocateAlpha(0,0,0,127); $im->fill(0,0,$transparent); $im->setAntiAliased($red); $im->setThickness(6); @prevpts = ( $center, $center + $radius ); for ($i=0;$i<=360;$i++) { @newpts = &RotatePointAroundOrigin($center, $center, $center, $center + $radius, $i); $im->line($prevpts[0], $prevpts[1], $newpts[0], $newpts[1], gdAntiAliased); @prevpts = @newpts; }This is what I used to generate test2.png. I see the same affect with arcs, but this demonstrates that lines are affected as well. When output to a PNG image, there are 2 problems:
1) The lines are anti-aliased against the wrong background color. If you view the image over a white background, you will see that the lines were anti-aliased against black (instead of anti-aliased using alpha, such as text rendered by stringFT would be). If you set the thickness to 1, you will see the same problem. This is a problem with anti-aliased lines (with thickness==1) and alpha transparency, and is not related to thickness >1 or arc's.
2) Angled lines are rendered differently than horizontal and vertical lines. In some conditions, you are are using the requested thickness and not anti-aliasing. In other conditions, you are anti-aliasing, but reducing the thickness to 1. Since my drawning code is independant of the output format, my suggestion would be to always disable anti-aliasing and use the requested thickness, when thickness >1 is requested. That would be the closest to the desired effect, and would make the image look more consistent across output formats.
- Colen
"This is what I used to generate test2.png. I see the same affect with arcs, but this demonstrates that lines are affected as well. When output to a PNG image, there are 2 problems:"
For clarity, there is only two buffer formats:
Each of this format can be saved to an image file or stream. Internally each file format support both or only one image type. PNG supports both, GIF supports only palette based image (we have to use dithering for truecolor iamge), jpeg support only truecolor image.
"The lines are anti-aliased against the wrong background color. If you view the image over a white background, you will see that the lines were anti-aliased against black (instead of anti-aliased using alpha, such as text rendered by stringFT would be)."
That's yet another problem. We do not support AA based on the alpha channel like what we do in the StringFT functions. By the way, it does not happen with a white background but when the backroung is completely transparent (gdTrueColorAlpha(0,0,0,127) in your example).
"Angled lines are rendered differently than horizontal and vertical lines. In some conditions, you are are using the requested thickness and not anti-aliasing."
The start and end of each line are pixel aligned (no partial coverage). There is no AA for axis aligned lines as they fit exactly on the pixels they cover. For a non axis aligned line, the ideal line (with a thickness of 1) will cover more than one pixel, for example 80% at (10,10) and 20% at (10,11) is the position for the pixel at (10.0, 10.20).
"my suggestion would be to always disable anti-aliasing and use the requested thickness, when thickness >1 is requested. That would be the closest to the desired effect, and would make the image look more consistent across output formats."
It sadly cannot be done now as it will suddenly bring some backward compatibility problem. I suggest you to manually disable AA when you have a thickness > 1. Doing so will help you to implement a function compatible with 2.1.0 and earlier version as well.
To bring at least one good news, 2.1.0 may support floating start/end points. It will greatly improve the complex shapes rendering and positioning.
I would you like to thank you again for the detailed feedbacks. It confirms the choices we made for 2.1.0 and gave us a couple of good test cases!
I will close this bug as the initial issue is fixed and the other problems described here are already reported in other bug reports (AA, arcs and lines with thickness and alpha values).
Initial problem is fixed in 2.0.35. Move it to 2.1.0 until a separate issue has been created for the other problem described here.