0

I am using DisplayJAI to highlight specific portion of image.

Application class

import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;

    public class DisplayIImages {
        final static float dash1[] = { 2.0f };
        final static BasicStroke dashed = new BasicStroke(1.0f,
              BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
        public static void main(String[] args) throws IOException
             {
            //PlanarImage image=JAI.create("scan", args[0]);
            File f= new File("profile.jpeg");
            RenderedImage image2=ImageIO.read(f);
               DisplayJAIWithAnnotations display = new DisplayJAIWithAnnotations(image2);
              // Create a circle annotation.

             RectangleAnnotation ca = new RectangleAnnotation(20,100,60,110);

              ca.setColor(Color.BLUE);
              ca.setStroke(dashed);
               // Add the annotation to the instance of DisplayJAIWithAnnotations.
              display.addAnnotation(ca);
               // Create a new Frame and set the DisplayJAIWithAnnotations.
              JFrame frame = new JFrame();
             frame.setTitle("Annotations over an image");
              frame.getContentPane().add(new JScrollPane(display));
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
              frame.setSize(500,200); // Set the frame size so we can scroll over large images. 
              frame.setVisible(true); 
               } 
    }

subclass of DisplayJAI

class DisplayJAIWithAnnotations extends DisplayJAI
    {
     protected ArrayList<DrawableAnnotation> annotations; // List of annotations that will be
                                                        // (non-interactively) drawn over the image.

     // Constructor for the class.

     public DisplayJAIWithAnnotations(RenderedImage image)
       {
       super(image); // Calls the constructor for DisplayJAI
       annotations = new ArrayList<DrawableAnnotation>(); // List that will held the drawings.
       }

     // This method paints the component and all its annotations.
     public void paintComponent(Graphics g)
       {
       super.paintComponent(g);
       Graphics2D g2d = (Graphics2D)g;
       for (DrawableAnnotation d:annotations) 
        {
         d.paint(g2d);
         }
       }

     // Add an annotation (instance of any class that inherits from DrawableAnnotation) to the list 
     // of annotations which will be drawn.
     public void addAnnotation(DrawableAnnotation a) 
       {
       annotations.add(a);  
       }

     }  

Annotation class to highlight rectangle portion of image

 class RectangleAnnotation extends DrawableAnnotation
       {
       private int x1,y1,x2,y2; // the corners of the rectangle.

       // Constructor for this class.
       public RectangleAnnotation(int x1,int y1,int x2,int y2)
         {
         this.x1 = x1;    this.y1 = y1;
         this.x2 = x2;    this.y2 = y2;
         }

       // Concrete implementation of the paint method.
       public void paint(Graphics2D g2d)
         {
           float[] dash = new float[]{4.0f, 4.0f};
           BasicStroke dashStroke = new BasicStroke(1.0f,
                   BasicStroke.CAP_BUTT,
                   BasicStroke.JOIN_BEVEL,
                   0.0f,
                   dash, 0);
         g2d.setColor(getColor());
        g2d.setStroke(getStroke());    
        g2d.drawRect(x1,y1,x2-x1,y2-y1);
        }

       } 

abstract class for painting rectangle

abstract class DrawableAnnotation {
    // The annotation color.
    private Color color = Color.BLACK;
    // The annotation stroke.
    private Stroke stroke = new BasicStroke(1f);

    // This method will draw the annotation, and must be implemented by
    // non-abstract classes.
    public abstract void paint(Graphics2D g2d);

    // Setter for the color.
    public void setColor(Color color) {
        this.color = color;
    }

    // Getter for the color.
    public Color getColor() {
        return color;
    }

    // Setter for the stroke.
    public void setStroke(Stroke stroke) {
        this.stroke = stroke;
    }

    // Getter for the stroke.
    public Stroke getStroke() {
        return stroke;
    }

}

This is my code and its working fine.But I want to draw dispalyJAI using Graphics2D instead of directly adding to frame.Is this possible?

User123
  • 71
  • 3
  • 14
  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). 2) Use a logical and consistent form of indenting code lines and blocks. The indentation is intended to make the flow of the code easier to follow! – Andrew Thompson May 29 '15 at 05:08

1 Answers1

1

The question comes to find that if you are using...

ImageIO.read(f);

to load the image, why you are not using BufferedImage, which Graphics#drawImage is capable of painting?

And instead, just using something like...

public class RectangleAnnotation extends JPanel {

    private BufferedImage img;
    private ArrayList<DrawableAnnotation> annotations

    // Constructor for this class.
    public RectangleAnnotation(BufferedImage img) {
        this.img = img;
        annotations = new ArrayList<DrawableAnnotation>();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(img, 0, 0, this);
        for (DrawableAnnotation d : annotations) {
            d.paint(g2d);
        }
    }

    public void addAnnotation(DrawableAnnotation a) {
        annotations.add(a);
    }
}

Which you would apply using something like...

    File f = new File("profile.jpeg");
    BufferedImage image2 = ImageIO.read(f);
    RectangleAnnotation display = new RectangleAnnotation(image2);
    // Create a circle annotation.

    RectangleAnnotation ca = new RectangleAnnotation(20, 100, 60, 110);

    ca.setColor(Color.BLUE);
    ca.setStroke(dashed);
    // Add the annotation to the instance of DisplayJAIWithAnnotations.
    display.addAnnotation(ca);

Of course, if you're still hell bent, you could look at the source code for DisplayJAI

@Override
protected void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;

    // empty component (no image)

    if ( source == null ) {
        g2d.setColor(getBackground());
        g2d.fillRect(0, 0, getWidth(), getHeight());
        return;
    }

    // account for borders
    Insets insets = getInsets();
    int tx = insets.left + originX;
    int ty = insets.top  + originY;

    // clear damaged component area
    Rectangle clipBounds = g2d.getClipBounds();
    g2d.setColor(getBackground());
    g2d.fillRect(clipBounds.x,
                 clipBounds.y,
                 clipBounds.width,
                 clipBounds.height);

    /**

        Translation moves the entire image within the container

    */
    affineTrans = new AffineTransform();
    affineTrans.setTransform( AffineTransform.getTranslateInstance(tx, ty) );
    if ( (sx != 0) && (sy != 0) )
       affineTrans.scale(sx, sy);

    g2d.drawRenderedImage(source, affineTrans);
}

Drawing Annotations DIRECTLY to the image...

You can't (or more importantly you shouldn't) try and get the rendered contents of a component, it's complicated, just trust me on that.

Instead, you can use a BufferedImage, which allows you to obtain a Graphics context to the image, which you can then paint directly to...

List<DrawableAnnotation> annotations = new ArrayList<>(25);
RectangleAnnotation ca = new RectangleAnnotation(20, 100, 60, 110);
ca.setColor(Color.BLUE);
ca.setStroke(dashed);
// Any other annotations...

File f = new File("profile.jpeg");
BufferedImage image2 = ImageIO.read(f);
Graphics2D g2d = image2.createGraphics();
g2d.drawImage(image2, x, y, null);
for (DrawableAnnotation d : annotations) {
    d.paint(g2d);
}
g2d.dispose();

From here, you can either use a JPanel and it's paintComponent to renderer it, or if you're felling lazy, a JLabel...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • *"Is possible to draw DisplayJAI object using graphics methods"* - No. `DisplayJAI` IS a `JPanel`. The basics demonstrated are how painting an image can be done – MadProgrammer May 29 '15 at 05:21
  • `BufferedImage` is capable of dividing itself up into [`subImage`s](http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#getSubimage(int,%20int,%20int,%20int)) which is probably more practical to your needs. – MadProgrammer May 29 '15 at 05:24
  • [`subImage` example](http://stackoverflow.com/questions/11819669/absolute-positioning-graphic-jpanel-inside-jframe-blocked-by-blank-sections/11820847#11820847) – MadProgrammer May 29 '15 at 05:38
  • I thought that's what you code was doing (drawing rectangles over a image)? You CAN'T use components directly via `Graphics`, components use `Graphics` to paint themselves. If you want to take greater control, then you need to custom a `JPanel`'s `paintComponent` to do what you want... – MadProgrammer May 29 '15 at 06:03
  • I'm not sure what you're asking for there, what is `imageComponent`? And what would you want do with it? – MadProgrammer May 29 '15 at 06:11
  • I want to get image annotated with rectangle.Is there any way to get it from displayJAI – User123 May 29 '15 at 06:15
  • Ahhh, okay, now I'm running in a direction with, no, BUT, there is away you can do it yourself... – MadProgrammer May 29 '15 at 06:17
  • If I'm on the same track now, you really want to be able to paint directly to the image, see update. This will only affect the image you have in memory, not the file itself (and you can reload the file to get the original back) – MadProgrammer May 29 '15 at 06:23
  • How to increment or decrement the rectangle while zooming image? – User123 Jun 09 '15 at 08:16
  • You can use a AffoneTransform to change the scale of the rioting Graphics context (painting the image after you've applied it) – MadProgrammer Jun 09 '15 at 08:53
  • can u give me samples – User123 Jun 09 '15 at 08:56
  • [Example](http://stackoverflow.com/questions/19643637/zoom-using-mouse-and-graphics/19646246#19646246) – MadProgrammer Jun 09 '15 at 21:54
  • this only for zooming complete image.I draw a rectangle over image.How to zoom this rectangle without changing the position of rectangle while zooming image and center the rectangle portion. – User123 Jun 10 '15 at 11:06
  • Same concept, just you first need to get the subimage represented by the rectangle, as [another example](http://stackoverflow.com/questions/18158550/zoom-box-for-area-around-mouse-location-on-screen/18158845#18158845) – MadProgrammer Jun 10 '15 at 11:32