Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / May 2008

Tip: Looking for answers? Try searching our database.

Erasing a line

Thread view: 
Kenneth P. Turvey - 16 May 2008 23:57 GMT
I'm using antialiasing and transparency in an app I'm writing and I'm
running into some difficulty with the intersection of the two.

Let me work up an example and post it here..  

Ok.  Well this is no good.  

I just wrote a SSCE and it doesn't display the issue I'm having.  I also
can't seem to locate where in my code it is happening.  

Maybe if I describe it someone might be able to give me an idea of where
to look.  I know this is a long shot.  Feel free to guess.  

I have an image and on top of it I draw a line with AlphaComposite.CLEAR
to clear it.  I do this a number of times so I have a clear area on the
image.  

Then I draw another line in black that is partially overlapping my
cleared area with anti-aliasing on.  

What I see is that the portion of the line that isn't overlapping the
cleared area is anti-aliased just fine, but the portion that is
overlapping the cleared area is not.  

Any guesses as to what I should be looking for in my code.  Note, the
image is getting passed around and copied during the operation.  It isn't
all quite as simple as I'm stating or it would be easy to find.  The
important point is that the image in black is drawn in one call to
graphics.drawLine().  I should also note that anti-aliasing isn't working
for the clear line drawn either.  It is only working for the portion of
the black line that isn't drawn on top of a transparent portion of the
image.  

Thanks for any help you can provide with this poor problem description.

Signature

Kenneth P. Turvey <kt-usenet@squeakydolphin.com>

Knute Johnson - 17 May 2008 01:12 GMT
> I'm using antialiasing and transparency in an app I'm writing and I'm
> running into some difficulty with the intersection of the two.
[quoted text clipped - 12 lines]
> to clear it.  I do this a number of times so I have a clear area on the
> image.  

Why do you do this?  By clear area do you mean white?

> Then I draw another line in black that is partially overlapping my
> cleared area with anti-aliasing on.  
>
> What I see is that the portion of the line that isn't overlapping the
> cleared area is anti-aliased just fine, but the portion that is
> overlapping the cleared area is not.  

What is it supposed to anti-alias with if it is clear?

> Any guesses as to what I should be looking for in my code.  Note, the
> image is getting passed around and copied during the operation.  It isn't
[quoted text clipped - 6 lines]
>
> Thanks for any help you can provide with this poor problem description.

You're probably going to have to make an SSCCE or give a little more
information.

Signature

Knute Johnson
email s/nospam/linux/

Kenneth P. Turvey - 17 May 2008 01:43 GMT
> What is it supposed to anti-alias with if it is clear?

I can show you what I'm expecting since that's what my SSCE is doing:

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Example extends JComponent {
   BufferedImage image;

   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) throws IOException {
       JFrame frame = new JFrame("Example");
       frame.setBounds(new Rectangle(0, 0, 200, 200));
       Example example = new Example(new File(args[0]));
       frame.add(example);
       frame.setVisible(true);
   }

   public Example(File imageFile) throws IOException {
       BufferedImage imageTemp = ImageIO.read(imageFile);
       // We need to make sure it has transparency
       image = new BufferedImage(imageTemp.getWidth(),
imageTemp.getHeight(),
               BufferedImage.TYPE_4BYTE_ABGR);
       Graphics2D graphics = image.createGraphics();
       graphics.drawImage(imageTemp, 0, 0, image.getWidth(),
               image.getHeight(), null);
       graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
       graphics.setStroke(new BasicStroke(16, BasicStroke.CAP_ROUND,
               BasicStroke.JOIN_ROUND));
       graphics.setColor(Color.BLACK);
       graphics.drawLine(0, 50, image.getWidth(), 60);
       graphics.setComposite(AlphaComposite.getInstance
(AlphaComposite.CLEAR));
       graphics.drawLine(0, 100, image.getWidth(), 120);
   }

   @Override
   protected void paintComponent(Graphics g) {
       super.paintComponent(g);
       Graphics2D graphics = (Graphics2D) g;
       graphics.drawImage(image, 0, 0, getWidth(), getHeight(), null);
   }
}

OK, if you run this and pass in an image on the command line, then you
will see that image drawn with two lines through it, both anti-aliased.  
The top one is black and the bottom one is completely transparent.  If
you look at it you'll see that the bottom line has pixels where the
transparency isn't just set to 0. Some of the pixels might have a
transparency of 0.25 or some such.  So the transparent line blends with
whatever the background is to make a line that is anti-aliased.  

This is what I'm expecting.  Unfortunately the code I'm working with
doesn't do that.  

I found the minimum change I need to make to demonstrate the problem, but
I can't simplify it or everything works.  Unfortunately I can't see
anyway to really simplify the code I'm working with.  It looks identical
to the above code.  I'm not sure what's going on.  

I just had a guess occur to me.  Maybe at some point the image is being
copied to a BufferedImage with only BIT_MASK transparency.  Would that
result in the behavior I've described?  That is no anti-aliasing in the
transparent region, but perfect anti-aliasing outside it?  

Anyway, the only method I'm changing to demonstrate the difference is
this:

   private void drawLine(Graphics2D graphics, int x1, int y1, int x2,
int y2,
           boolean clear, Color color) {
       graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
        x1 -= getXPosition();
        x2 -= getXPosition();
        y1 -= getYPosition();
        y2 -= getYPosition();
        x1 *= 1.0/getScaleFactor();
        y1 *= 1.0/getScaleFactor();
        x2 *= 1.0/getScaleFactor();
        y2 *= 1.0/getScaleFactor();
       graphics.setStroke(new BasicStroke(eraserSize,
BasicStroke.CAP_ROUND,
               BasicStroke.JOIN_ROUND));
       logger.finest("Drawing line: "
               + x1 + ", " + y1 + ", " + x2 + ", " + y2);
       if (clear) {
           graphics.setComposite(AlphaComposite.getInstance
(AlphaComposite.CLEAR));
       } else if (color != null) {
           graphics.setColor(color);
       }
       graphics.drawLine(x1, y1, x2, y2);
       graphics.dispose();
   }

If I call this method with a non-null Color and false in the argument,
clear, then I get an anti-aliased line (as long as it doesn't intersect a
completely transparent portion of the image).  

If I call this method with a true in the argument, clear, then I get a
line that is not anti-aliased.

Signature

Kenneth P. Turvey <kt-usenet@squeakydolphin.com>

Kenneth P. Turvey - 17 May 2008 01:58 GMT
On Sat, 17 May 2008 00:43:42 +0000, I wrote:

> I just had a guess occur to me.  Maybe at some point the image is being
> copied to a BufferedImage with only BIT_MASK transparency.  Would that
> result in the behavior I've described?  That is no anti-aliasing in the
> transparent region, but perfect anti-aliasing outside it?

Problem solved.  This was it.  I did a search through the code for
Tranparency and found a Transparency.BITMASK in a super class.  So when I
called this code, the transparency was flattened to either a 0 or a 1.  
The anti-aliasing over the non-transparent areas was still OK, but where
there was transparency it was destroyed.  

Thanks for looking at this for me.

Signature

Kenneth P. Turvey <kt-usenet@squeakydolphin.com>



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.