javazoid
Junior Member  
Where's Flender?
|
 |
«
Posted
2003-10-31 10:07:58 » |
|
Java2D quality issues hello, I'm making deep use of java2d (I simply love it) for the creation of animated desktop video graphics and video titling. During the development of my applications I have discovered a bug in drawImage() http://developer.java.sun.com/developer/bugParade/bugs/4916948.html that causes incorrect results when drawing images with a translation-only AffineTransform. I also found a workaround for the problem, but I still hope that SUN fixes it asap. Now I'm facing a pair of issues of which can deeply impact the graphical output quality of any java2d program. Consider that we're drawing with the best rendering hints: interpolation, anti-aliasing etc. 1) drawImage() bilinear interpolation gives ugly results on ARGB images. consider the 2x2 bitmap pixels : X0 00 where X is completely transparent (let's say a transparent RED -> 0x00FF0000) and 0 is opaque (let's say an opaque WHITE -> 0xFFFFFFFF). The pixel bilinear interpolation takes the color of the X pixel into consideration. That's completely wrong because the pixel is transparent. When drawing the bitmap at 0.5,0.5 over a clean graphics (0x00000000) the pixel interpolator of java2d gives ugly red artifacts. 2) draw() renders low-quality shapes. An example: the on-screen quality a simple basicStroke'd text is far from being perfect with font sizes smaller than 30-40 points. Anyone can figure out this by simply comparing the results of java2d with a vector graphics package like CorelDraw. And the question is: will the situation change in jdk1.5 ? Cheers, Michele Puccini - ClassX Development ( mik@classx.it) --
|
|
|
|
tom
|
 |
«
Reply #1 - Posted
2003-10-31 12:39:27 » |
|
1) This is the correct way of doing bilinear interpolation. The fix is of course to not have contrasting colors in the transparent areas.
|
|
|
|
princec
|
 |
«
Reply #2 - Posted
2003-10-31 13:14:02 » |
|
Isn't there a renderinghint that causes alpha to be treated in a special way? Cas 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
swpalmer
|
 |
«
Reply #3 - Posted
2003-10-31 14:53:58 » |
|
1) This is the correct way of doing bilinear interpolation. The fix is of course to not have contrasting colors in the transparent areas. Are you certain about that? I would have expected that the interpolation of the colour data needs to account for the alpha data at the same time. e.g.: 1 2 3 4
| float L = 0.5; Cout = C1 * (L) + C2 *(1-L); float F1 = L*(A1/(A1+A2)); Cbetter = C1 * F1 + C2 * (1-F1); |
I didn't test the above method. Am I making sense?
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #4 - Posted
2003-11-01 09:45:47 » |
|
Well, I posted a little test image: http://www.classx.it/public/bilerp_test.pngLooking at the image it clearly appears how java2d takes the tint of the red transparent pixels into account. That's a wrong behaviour this causes ugly artifacts when drawing transformed-bilerped transparent images. Comments ? How does the new MacOSX java imlementation handle this ? I know that they redirect java2d calls on Quartz. Cheers, Mik
|
|
|
|
Orangy Tang
|
 |
«
Reply #5 - Posted
2003-11-01 10:23:27 » |
|
I don't know what the official spec for j2d is, but for OpenGL this is normal filtering behaviour. The colours are interpolated as normal, then the alpha in interpolated separatly and applied to the new colour. If you want the behaviour seen in PSP then you just need to duplicate the colours around the edge.
BTW, i'm pretty sure that PSP doesn't do bilinear filtering on its rotations, but it does do anti-aliasing which would give smoother edges like you're seeing.
|
|
|
|
tom
|
 |
«
Reply #6 - Posted
2003-11-01 14:12:54 » |
|
I reproduced your test images in both paint shop pro 8 and in java2d. But I got a pink edge in both psp as in java2d. How did you create your psp image? This is what I did: 1. I programmed an image with the specified source image and source alpha. A wrote the image to disk using my tga saver. It's easier than finding out how to create the image in psp 2. loaded the tga in psp. 3. loaded mask from image alpha 4. added white layer behind loaded image. 5. rotated layer with loaded image a couple of degrees. The result is a black square with a pink edge around it. I took a quick look at the rendering hints, but found no way of removing the bleed without turning off filtering. I can be wrong though, I'm no java2d expert. It is however possible in opengl. Here you use "glAlphaFunc(GL_EQUAL, 1)" (disclaimer: not tested, and can be wrong :-/ ). This will remove any color bleed along with half of the opaque pixels bordering with transparent pixels. This will also give a hard edge, and will not look antialiased  The solution is to not have a contrasting color at the bordering transparent pixels. It's even easy to write a routine that fixes the problem: 1 2 3 4 5 6
| for each pixel in image { if (pixel.alpha is transparent) and (a neighboring pixel is opaque) { pixel.colorRGB = average color of neighboring opaque pixels } } |
|
|
|
|
swpalmer
|
 |
«
Reply #7 - Posted
2003-11-02 00:19:28 » |
|
How does the new MacOSX java implementation handle this ? I know that they redirect java2d calls on Quartz.
I'm not 100% certain that the rotation will be done with quartz, but if you can point me to you test code I'll run it on my Mac and let you know the results.
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #8 - Posted
2003-11-02 16:51:36 » |
|
Hi swpalmer, here's an executable jar (very raw src included). http://www.classx.it/public/bilerp_test.jarGive it a run. Should work on MacOSX java .. The test shows a pair of test graphics. The one at left is bilerped and you can notice those ugly red pixels around. Cheers, Mik
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #9 - Posted
2003-11-02 17:05:10 » |
|
I reproduced your test images in both paint shop pro 8 and in java2d. But I got a pink edge in both psp as in java2d. How did you create your psp image?
1) Just donwload the java2d-rendered TGA pic from http://www.classx.it/public/txt.tga2) load it in PSP 3) do a "selection/load from alpha channel" 4) hit CTRL-C, create a new white image and hit CTRL-E 5) Rotate the selection with the deformation tool. And.. yes, your pseudo-code looks correct. Now it's all up to the SUN Java2D team !! Cheers, Mik
|
|
|
|
Games published by our own members! Check 'em out!
|
|
tom
|
 |
«
Reply #10 - Posted
2003-11-02 19:27:48 » |
|
You are NOT using a transparent image in PSP!!! You are using a selection, which is a vector based shape. So you are comparing apples and oranges 
|
|
|
|
tom
|
 |
«
Reply #11 - Posted
2003-11-02 19:40:44 » |
|
...and the pseudocode was ment for you 
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #12 - Posted
2003-11-03 06:09:23 » |
|
Sorry tom, but I think you're wrong.
The outline you see is not a vector, but the edges of the non-transparent pixels. PSP doesn't mistake.
Cheers,
Mik
|
|
|
|
swpalmer
|
 |
«
Reply #13 - Posted
2003-11-04 00:45:08 » |
|
I tried, but the download kept timing out before it got started 
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #14 - Posted
2003-11-04 06:00:38 » |
|
Gosh! Should work right now. It's only 6kb so I suppose it shouldn't take that much.. 
|
|
|
|
|
|
Abuse
|
 |
«
Reply #16 - Posted
2003-11-04 12:40:06 » |
|
time for a bug report then 
|
Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! 
|
|
|
|
|
tom
|
 |
«
Reply #18 - Posted
2003-11-05 09:24:47 » |
|
|
|
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #20 - Posted
2003-11-05 16:41:17 » |
|
TOM & the others,
sadly that ARGB_PRE trick doesn't work at all. I get even bad results. Bad luck :-/
Let's hope the win32 Java2D team will fix the bug asap.
|
|
|
|
trembovetski
|
 |
«
Reply #21 - Posted
2003-11-10 06:07:57 » |
|
Well, it's not really a win32-specific issue (the bug is reproducible with -Dsun.java2d.noddraw=true, which pretty much disables any win32-specific hw acceleration), but the way our software loops do it. You don't see it on mac because they're doing it through hw.
Unfortunately, the bug is still there in current build of 1.5. I'll see if our opengl pipeline on linux/solaris does any better tomorrow..
|
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #22 - Posted
2003-11-10 07:15:48 » |
|
trembovetski,
as you know the bug deeply impacts the quality of all java2d-based programs and it's so sad to hear that it's also in 1.5.
How can I help to fix it for 1.4.3 and 1.5 ?
Cheers,
Mik
|
|
|
|
trembovetski
|
 |
«
Reply #23 - Posted
2003-11-11 02:21:15 » |
|
How can I help to fix it for 1.4.3 and 1.5 ?
Well, let me just give you my paypal account =) Seriously, though, you can vote on the bug. I'll let the engineer who works on this bug know about this thread. As I've explained in some other thread, the bugs chosen to be fixed in patch releases (_01, _02, etc) have to be escalated, or considered extremely important (like security issues). It also depends on how risky the fix is. It can definitely be fixed in the next maintenance relelase (1.5.1), but it's still way off. There's still some time left for 1.5, so it may get fixed, it depends on a number of factors (how risky is the fix, etc). In any case, one thing you can do is to vote on the bug, be vocal on 1.5 beta feedback, and suggest a good business case for why this bug is important.
|
|
|
|
|
javazoid
Junior Member  
Where's Flender?
|
 |
«
Reply #24 - Posted
2003-11-11 06:30:51 » |
|
This kind of fix should not be _that_ risky  Seriously, how can I reach the 1.5 mail lists ? Cheers, Mik
|
|
|
|
Abuse
|
 |
«
Reply #25 - Posted
2003-11-11 08:23:57 » |
|
Theres no risk at all, so long as the coder doesn't c0ck up the fix  Damn I should be in risk managment 
|
Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! 
|
|
|
|