Area generation not liking straight lines - java

I'm using the area generation and drawing code from Smoothing a jagged path to create collision areas for tile sprites in a JRPG game I'm making in java - Its not a major full blown game, more just a proof-of-concept for me to learn from.
The area generation works fine except for straight lines:
http://puu.sh/7wJA2.png
http://puu.sh/7wJGF.png
These images are of the collision outline opened in photoshop (in the background) vs the area that the java code is generating based on the red color (in the foreground). As can be seen, the large red line in the first image won't be draw unless I have a red pixel under it every 2 pixels, as shown in the second image.
I have made no changes to the code (other than adding comments in an attempt to better understand it) except to remove
Graphics2D g = imageOutline.createGraphics();
//...
g.dispose();
from the areaOutline draw code, replacing it with reference to my own Graphics2D variable. I tested the code both with and without those two lines and I couldn't see any difference.
I'm a bit stuck on what could be causing the issue - its not a major game-breaking issue, as I can fix it a couple of ways, but it does mean I have to explain this issue to anyone when showing them how to use it with their own sprite textures.
I've created a SSCCE of the issue - This shows the areas generated have vertical lines generated fine, but that horizontal ones are not. It takes two images - both a square 30x30 pixels, but one has internal pixels every 2 second pixel in which causes a more accurate area to be generated.
When you press a key the program will switch between the two images (and their areas), allowing for direct comparison.
The following two images must be put in the root folder of the program.
You can start the program by running the "main" method.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.io.*;
import javax.imageio.*;
public class AreaOutlineCanvas extends JFrame implements KeyListener
{
private ImagePanel imagePanel;
/**
* Constructor for objects of class Skeleton
*/
public AreaOutlineCanvas()
{
// initialise instance variables
addKeyListener( this );
initUI();
}
public static void main( String[] args )
{
for( String s: args )
{
System.out.println( s );
}
SwingUtilities.invokeLater( new Runnable()
{
#Override
public void run()
{
AreaOutlineCanvas aOC = new AreaOutlineCanvas();
aOC.pack();
aOC.setVisible( true );
aOC.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} );
}
private void initUI()
{
imagePanel = new ImagePanel();
setPreferredSize( new Dimension( 100, 100 ) );
setLocationRelativeTo( null );
add( imagePanel );
imagePanel.setDoubleBuffered( true );
pack();
}
#Override
public void keyTyped( KeyEvent e )
{
}
#Override
public void keyPressed( KeyEvent e )
{
//#TODO: switch statment checking the menu Skeleton is in (currentMenu)
if( imagePanel != null )
{
imagePanel.bDrawingFirstArea = !imagePanel.bDrawingFirstArea;
imagePanel.repaint();
}
}
#Override
public void keyReleased(KeyEvent e)
{
//System.out.println( "Key released: " + e.getKeyChar() + " (" + e.getKeyCode() + ")" );
}
public class ImagePanel extends JPanel
{
/** Path for the location of this charactors sprite sheet */
private String firstPath = "square1.png";
private String secondPath = "square2.png";
private BufferedImage firstImage;
private BufferedImage secondImage;
private Area firstImageArea;
private Area secondImageArea;
public boolean bDrawingFirstArea = true;
/**
* Constructor for objects of class Character
*/
public ImagePanel()
{
loadImages();
generateAreas();
}
private void loadImages()
{
try
{
firstImage = ImageIO.read( new File( firstPath ) );
secondImage = ImageIO.read( new File( secondPath ) );
}
catch( IOException e )
{
e.printStackTrace();
}
}
private void generateAreas()
{
Color c = new Color( 255, 0, 0 );
firstImageArea = getOutline( c, firstImage );
secondImageArea = getOutline( c, secondImage );
}
public Area getOutline(Color target, BufferedImage bi) {
// construct the GeneralPath
GeneralPath gp = new GeneralPath();
boolean cont = false;
int targetRGB = target.getRGB();
for (int xx=0; xx<bi.getWidth(); xx++) {
for (int yy=0; yy<bi.getHeight(); yy++) {
if (bi.getRGB(xx,yy)==targetRGB) {
if (cont) {
gp.lineTo(xx,yy);
gp.lineTo(xx,yy+1);
gp.lineTo(xx+1,yy+1);
gp.lineTo(xx+1,yy);
gp.lineTo(xx,yy);
} else {
gp.moveTo(xx,yy);
}
cont = true;
} else {
cont = false;
}
}
cont = false;
}
gp.closePath();
// construct the Area from the GP & return it
return new Area(gp);
}
#Override
public void paintComponent( Graphics g )
{
super.paintComponent( g );
drawImages(g);
}
private void drawImages( Graphics g )
{
Graphics2D g2d = (Graphics2D) g;
if( bDrawingFirstArea )
{
g2d.drawImage( firstImage, 50, 0, this );
g2d.draw( firstImageArea );
}
else
{
g2d.drawImage( secondImage, 50, 0, this );
g2d.draw( secondImageArea );
}
Toolkit.getDefaultToolkit().sync();
}
}
}
For convenience I've posted the code from Smoothing a jagged path question here
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
/* Gain the outline of an image for further processing. */
class ImageOutline {
private BufferedImage image;
private TwoToneImageFilter twoToneFilter;
private BufferedImage imageTwoTone;
private JLabel labelTwoTone;
private BufferedImage imageOutline;
private Area areaOutline = null;
private JLabel labelOutline;
private JLabel targetColor;
private JSlider tolerance;
private JProgressBar progress;
private SwingWorker sw;
public ImageOutline(BufferedImage image) {
this.image = image;
imageTwoTone = new BufferedImage(
image.getWidth(),
image.getHeight(),
BufferedImage.TYPE_INT_RGB);
}
public void drawOutline() {
if (areaOutline!=null) {
Graphics2D g = imageOutline.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0,0,imageOutline.getWidth(),imageOutline.getHeight());
g.setColor(Color.RED);
g.setClip(areaOutline);
g.fillRect(0,0,imageOutline.getWidth(),imageOutline.getHeight());
g.setColor(Color.BLACK);
g.setClip(null);
g.draw(areaOutline);
g.dispose();
}
}
public Area getOutline(Color target, BufferedImage bi) {
// construct the GeneralPath
GeneralPath gp = new GeneralPath();
boolean cont = false;
int targetRGB = target.getRGB();
for (int xx=0; xx<bi.getWidth(); xx++) {
for (int yy=0; yy<bi.getHeight(); yy++) {
if (bi.getRGB(xx,yy)==targetRGB) {
if (cont) {
gp.lineTo(xx,yy);
gp.lineTo(xx,yy+1);
gp.lineTo(xx+1,yy+1);
gp.lineTo(xx+1,yy);
gp.lineTo(xx,yy);
} else {
gp.moveTo(xx,yy);
}
cont = true;
} else {
cont = false;
}
}
cont = false;
}
gp.closePath();
// construct the Area from the GP & return it
return new Area(gp);
}
public JPanel getGui() {
JPanel images = new JPanel(new GridLayout(2,2,2,2));
JPanel gui = new JPanel(new BorderLayout(3,3));
JPanel originalImage = new JPanel(new BorderLayout(2,2));
final JLabel originalLabel = new JLabel(new ImageIcon(image));
targetColor = new JLabel("Target Color");
targetColor.setForeground(Color.RED);
targetColor.setBackground(Color.WHITE);
targetColor.setBorder(new LineBorder(Color.BLACK));
targetColor.setOpaque(true);
JPanel controls = new JPanel(new BorderLayout());
controls.add(targetColor, BorderLayout.WEST);
originalLabel.addMouseListener( new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
originalLabel.setCursor(
Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
#Override
public void mouseExited(MouseEvent me) {
originalLabel.setCursor(Cursor.getDefaultCursor());
}
#Override
public void mouseClicked(MouseEvent me) {
int x = me.getX();
int y = me.getY();
Color c = new Color( image.getRGB(x,y) );
targetColor.setBackground( c );
updateImages();
}
});
originalImage.add(originalLabel);
tolerance = new JSlider(
JSlider.HORIZONTAL,
0,
255,
104
);
tolerance.addChangeListener( new ChangeListener() {
public void stateChanged(ChangeEvent ce) {
updateImages();
}
});
controls.add(tolerance, BorderLayout.CENTER);
gui.add(controls,BorderLayout.NORTH);
images.add(originalImage);
labelTwoTone = new JLabel(new ImageIcon(imageTwoTone));
images.add(labelTwoTone);
images.add(new JLabel("Smoothed Outline"));
imageOutline = new BufferedImage(
image.getWidth(),
image.getHeight(),
BufferedImage.TYPE_INT_RGB
);
labelOutline = new JLabel(new ImageIcon(imageOutline));
images.add(labelOutline);
updateImages();
progress = new JProgressBar();
gui.add(images, BorderLayout.CENTER);
gui.add(progress, BorderLayout.SOUTH);
return gui;
}
private void updateImages() {
if (sw!=null) {
sw.cancel(true);
}
sw = new SwingWorker() {
#Override
public String doInBackground() {
progress.setIndeterminate(true);
adjustTwoToneImage();
labelTwoTone.repaint();
areaOutline = getOutline(Color.BLACK, imageTwoTone);
drawOutline();
return "";
}
#Override
protected void done() {
labelOutline.repaint();
progress.setIndeterminate(false);
}
};
sw.execute();
}
public void adjustTwoToneImage() {
twoToneFilter = new TwoToneImageFilter(
targetColor.getBackground(),
tolerance.getValue());
Graphics2D g = imageTwoTone.createGraphics();
g.drawImage(image, twoToneFilter, 0, 0);
g.dispose();
}
public static void main(String[] args) throws Exception {
int size = 150;
final BufferedImage outline =
new BufferedImage(size,size,BufferedImage.TYPE_INT_RGB);
Graphics2D g = outline.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0,0,size,size);
g.setRenderingHint(
RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Polygon p = new Polygon();
p.addPoint(size/2, size/10);
p.addPoint(size-10, size-10);
p.addPoint(10, size-10);
Area a = new Area(p);
Rectangle r = new Rectangle(size/4, 8*size/10, size/2, 2*size/10);
a.subtract(new Area(r));
int radius = size/10;
Ellipse2D.Double c = new Ellipse2D.Double(
(size/2)-radius,
(size/2)-radius,
2*radius,
2*radius
);
a.subtract(new Area(c));
g.setColor(Color.BLACK);
g.fill(a);
ImageOutline io = new ImageOutline(outline);
JFrame f = new JFrame("Image Outline");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(io.getGui());
f.pack();
f.setResizable(false);
f.setLocationByPlatform(true);
f.setVisible(true);
}
}
class TwoToneImageFilter implements BufferedImageOp {
Color target;
int tolerance;
TwoToneImageFilter(Color target, int tolerance) {
this.target = target;
this.tolerance = tolerance;
}
private boolean isIncluded(Color pixel) {
int rT = target.getRed();
int gT = target.getGreen();
int bT = target.getBlue();
int rP = pixel.getRed();
int gP = pixel.getGreen();
int bP = pixel.getBlue();
return(
(rP-tolerance<=rT) && (rT<=rP+tolerance) &&
(gP-tolerance<=gT) && (gT<=gP+tolerance) &&
(bP-tolerance<=bT) && (bT<=bP+tolerance) );
}
public BufferedImage createCompatibleDestImage(
BufferedImage src,
ColorModel destCM) {
BufferedImage bi = new BufferedImage(
src.getWidth(),
src.getHeight(),
BufferedImage.TYPE_INT_RGB);
return bi;
}
public BufferedImage filter(
BufferedImage src,
BufferedImage dest) {
if (dest==null) {
dest = createCompatibleDestImage(src, null);
}
for (int x=0; x<src.getWidth(); x++) {
for (int y=0; y<src.getHeight(); y++) {
Color pixel = new Color(src.getRGB(x,y));
Color write = Color.BLACK;
if (isIncluded(pixel)) {
write = Color.WHITE;
}
dest.setRGB(x,y,write.getRGB());
}
}
return dest;
}
public Rectangle2D getBounds2D(BufferedImage src) {
return new Rectangle2D.Double(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D(
Point2D srcPt,
Point2D dstPt) {
// no co-ord translation
return srcPt;
}
public RenderingHints getRenderingHints() {
return null;
}
}

Related

How to use tooltips on rectangle created by mouse movement - Java

I am creating a rectangle with my mouse and i'm just trying to return info from the created object with a mouseover. I've been solving this with a messabox but there's just not many country to mouseover so the number of popup can be monstrous.
I decided to use a tooltip. Thing is it's not working on my mouse over :
JTextField text = new JTextField();
if (coordX > coordXRec && coordX < coordXRec + width && coordY > coordYrec && coordY < coordYrec + height){
text.setToolTipText(i.GetInfoPays());
text.getToolTipText();
}
Naturally, i want it to show when i mouseover my rectangle created :
That green rectangle was made by the user so i can't 'preset' an event
or use it as a panel for my tooltip.
This is what excepted, but using a tooltiptext, not a messabox.
I've been using a MouseEventMoved to know if im hovering over my rectangle. Its working but i'm stuck at sort of changing my messagebox into a tooltip.
Use setToolTipText("..."); with the appropriate String when needed (e.g. during paintComponent()).
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.*;
public class MouseShapeDetection {
private JComponent ui = null;
MouseShapeDetection() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(new ShapePanel());
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
MouseShapeDetection o = new MouseShapeDetection();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
class ShapePanel extends JPanel {
Point point = new Point(0, 0);
Dimension preferredSize = new Dimension(600, 300);
ArrayList<Shape> shapes = new ArrayList<>();
Color translucent = new Color(0,0,255,87);
Color selectedColor = Color.GREEN;
Color unselectedColor = Color.RED;
public ShapePanel() {
this.addMouseMotionListener(new MotionListener());
setBackground(Color.WHITE);
Random r = new Random();
int x, y, w, h, wP = preferredSize.width, hP = preferredSize.height;
for (int ii = 0; ii < 40; ii++) {
w = r.nextInt(100)+40;
h = r.nextInt(50)+20;
x = r.nextInt(wP - w);
y = r.nextInt(hP - h);
Ellipse2D.Double ellipse = new Ellipse2D.Double(x, y, w, h);
shapes.add(ellipse);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
StringBuilder sb = new StringBuilder("Shapes: ");
Graphics2D g2 = (Graphics2D)g;
for (int ii=0; ii<shapes.size(); ii++) {
Shape shape = shapes.get(ii);
g2.setColor(translucent);
g2.fill(shape);
if (shape.contains(point)) {
g2.setColor(selectedColor);
sb.append(ii);
sb.append(" ");
} else {
g2.setColor(unselectedColor);
}
g2.setStroke(new BasicStroke(2.5f));
g2.draw(shape);
}
setToolTipText(sb.toString());
}
#Override
public Dimension getPreferredSize() {
return preferredSize;
}
class MotionListener extends MouseMotionAdapter {
#Override
public void mouseMoved(MouseEvent e) {
point = e.getPoint();
repaint();
}
}
}

Drawing shapes in JPanel over an image

I need to draw shapes (circle or free line) over an image that is shown in a JLabel of a JPanel.
I based my code on the questions How to draw thin line with no gap while dragging the cursor? and Draw a circle using 2 mouse clicks.
The code is bellow. The problem is that when I start drawing the image disappears and only reappears after I stop.
If I comment the line super.paintComponent(g); that doesnt happen but when I draw the circle it maintains a path of the previous positions.
public static void main(String args[]) {
try {
URL url = new URL("http://www.senhoritatours.com/wp-content/uploads/2014/05/Porto-.jpg");
backgroundImage = ImageIO.read(url);
} catch (Exception e) {
e.printStackTrace();
}
loadAnnotation();
loadBackground();
JFrame f;
f = new JFrame();
f.setLayout(new BorderLayout());
f.add(mp);
f.pack();
f.setVisible(true);
}
/* Layer 0:
* Load background picture */
public static void loadBackground() {
JLabel lbImg = new JLabel();
lbImg.setBounds(0, 0, new ImageIcon(backgroundImage).getIconWidth(), new ImageIcon(backgroundImage).getIconHeight());
lbImg.setIcon(new ImageIcon(backgroundImage));
mp = new JPanel(new BorderLayout());
btnCircle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(btnCircle.isEnabled())
{
btnCircle.setEnabled(false);
btnLine.setEnabled(true);
}
}
});
btnLine.setEnabled(true);
btnCircle.setEnabled(false);
btnLine.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(btnLine.isEnabled())
{
btnLine.setEnabled(false);
btnCircle.setEnabled(true);
}
}
});
mp.add(btnCircle);
mp.add(btnLine);
mp.add(lbImg);
mp.add(p);
}
/* Layer 1:
* Annotation: Draw on top of background picture anything! */
public static void loadAnnotation() {
p = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.RED);
if (_bufImage == null) {
int w = this.getWidth();
int h = this.getHeight();
_bufImage = new BufferedImage(1024,600, BufferedImage.TRANSLUCENT);
Graphics2D gc = _bufImage.createGraphics();
}
g2.drawImage(_bufImage, null, 0, 0);
if (_state == State.DRAGGING) {
if (!btnLine.isEnabled())
{
g.drawLine(_start.x, _start.y, _end.x , _end.y);
}
}
if (!btnCircle.isEnabled())
{
g.drawOval(x, y, width, height);
}
}
public Dimension getPreferredSize() {
return new Dimension(1024, 600);
}
};
p.setLayout(new OverlayLayout(p));
p.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent me) {
}
#Override
public void mousePressed(MouseEvent me) {
last = me.getPoint();
dragging = isInsideEllipse(last);
if (!dragging) {
x = last.x;
y = last.y;
width = 0;
height = 0;
}
p.repaint();
}
#Override
public void mouseReleased(MouseEvent me) {
//_state = State.IDLE;
last = null;
dragging = false;
_state = State.IDLE;
p.repaint();
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
});
p.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent me) {
if(!btnLine.isEnabled())
{
_state = State.DRAGGING;
_end = me.getPoint();
if (_state == State.DRAGGING) {
Graphics2D g2 = _bufImage.createGraphics();
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(2));
g2.drawLine(_start.x, _start.y, _end.x, _end.y);
p.repaint();
//
}
_start = _end;
}
else
{
int dx = me.getX() - last.x;
int dy = me.getY() - last.y;
if (dragging) {
x += dx;
y += dy;
} else {
width += dx;
height += dy;
}
last = me.getPoint();
p.repaint();
}
}
#Override
public void mouseMoved(MouseEvent me) {
//System.out.println("move");
_start = me.getPoint();
}
});
}
Either
Display the image in the same paintComponent method that you're doing your drawing in, via Graphics#drawImage(...). You would call this immediately after the super.paintComponent(g) call.
Or do your drawing in the paintComponent(...) method of your JLabel, the one displaying the image.
For example:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawingPanel extends JPanel {
private final static String PATH = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/7/7c/Thomas_Hicks_-_Leopold_Grozelier_-_Presidential_Candidate_"
+ "Abraham_Lincoln_1860_-_cropped_to_lithographic_plate.jpg/"
+ "463px-Thomas_Hicks_-_Leopold_Grozelier_-_Presidential_Candidate_"
+ "Abraham_Lincoln_1860_-_cropped_to_lithographic_plate.jpg";
private static final Color DRAWING_COLOR = new Color(255, 100, 200);
private static final Color FINAL_DRAWING_COLOR = Color.red;
private BufferedImage backgroundImg;
private Point startPt = null;
private Point endPt = null;
private Point currentPt = null;
private int prefW;
private int prefH;
public DrawingPanel() throws IOException {
URL imgUrl = new URL(PATH);
BufferedImage bImg = ImageIO.read(imgUrl);
prefW = bImg.getWidth();
prefH = bImg.getHeight();
backgroundImg = new BufferedImage(prefW, prefH,
BufferedImage.TYPE_INT_ARGB);
Graphics g = backgroundImg.getGraphics();
g.drawImage(bImg, 0, 0, this);
g.dispose();
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseMotionListener(myMouseAdapter);
addMouseListener(myMouseAdapter);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
if (startPt != null && currentPt != null) {
g.setColor(DRAWING_COLOR);
int x = Math.min(startPt.x, currentPt.x);
int y = Math.min(startPt.y, currentPt.y);
int width = Math.abs(startPt.x - currentPt.x);
int height = Math.abs(startPt.y - currentPt.y);
g.drawRect(x, y, width, height);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(prefW, prefH);
}
public void drawToBackground() {
Graphics g = backgroundImg.getGraphics();
g.setColor(FINAL_DRAWING_COLOR);
int x = Math.min(startPt.x, endPt.x);
int y = Math.min(startPt.y, endPt.y);
int width = Math.abs(startPt.x - endPt.x);
int height = Math.abs(startPt.y - endPt.y);
g.drawRect(x, y, width, height);
g.dispose();
startPt = null;
repaint();
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseDragged(MouseEvent mEvt) {
currentPt = mEvt.getPoint();
DrawingPanel.this.repaint();
}
#Override
public void mouseReleased(MouseEvent mEvt) {
endPt = mEvt.getPoint();
currentPt = null;
drawToBackground();
}
#Override
public void mousePressed(MouseEvent mEvt) {
startPt = mEvt.getPoint();
}
}
private static void createAndShowGui() {
DrawingPanel mainPanel = null;
try {
mainPanel = new DrawingPanel();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("Drawing Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Select, Copy and Paste Images

What I want my app to do:
1 - Select an area of Image and get the coordinates. This code below should do this:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class ScreenCaptureRectangle {
Rectangle captureRect;
ScreenCaptureRectangle(final BufferedImage screen) {
final BufferedImage screenCopy = new BufferedImage(
screen.getWidth(),
screen.getHeight(),
screen.getType());
final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy));
JScrollPane screenScroll = new JScrollPane(screenLabel);
screenScroll.setPreferredSize(new Dimension(
(int)(screen.getWidth()/3),
(int)(screen.getHeight()/3)));
JPanel panel = new JPanel(new BorderLayout());
panel.add(screenScroll, BorderLayout.CENTER);
final JLabel selectionLabel = new JLabel(
"Drag a rectangle in the screen shot!");
panel.add(selectionLabel, BorderLayout.SOUTH);
repaint(screen, screenCopy);
screenLabel.repaint();
screenLabel.addMouseMotionListener(new MouseMotionAdapter() {
Point start = new Point();
#Override
public void mouseMoved(MouseEvent me) {
start = me.getPoint();
repaint(screen, screenCopy);
selectionLabel.setText("Start Point: " + start);
screenLabel.repaint();
}
#Override
public void mouseDragged(MouseEvent me) {
Point end = me.getPoint();
captureRect = new Rectangle(start,
new Dimension(end.x-start.x, end.y-start.y));
repaint(screen, screenCopy);
screenLabel.repaint();
selectionLabel.setText("Rectangle: " + captureRect);
}
});
JOptionPane.showMessageDialog(null, panel);
System.out.println("Rectangle of interest: " + captureRect);
}
public void repaint(BufferedImage orig, BufferedImage copy) {
Graphics2D g = copy.createGraphics();
g.drawImage(orig,0,0, null);
if (captureRect!=null) {
g.setColor(Color.RED);
g.draw(captureRect);
g.setColor(new Color(255,255,255,150));
g.fill(captureRect);
}
g.dispose();
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
final Dimension screenSize = Toolkit.getDefaultToolkit().
getScreenSize();
final BufferedImage screen = robot.createScreenCapture(
new Rectangle(screenSize));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ScreenCaptureRectangle(screen);
}
});
}
}
2 - get the coordinates and use it on getSubimage method.
double w = captureRect.getWidth();
double h = captureRect.getHeight();
double x = captureRect.getX();
double y = captureRect.getY();
int W = (int) w;
int H = (int) h;
int X = (int) x;
int Y = (int) y;
BufferedImage selectImg = screen.getSubimage(x, y, w, h);
3 - this code create a new image file and copy the imageselected.
BufferedImage img = new BufferedImage ( 5000, 5000, BufferedImage.TYPE_INT_RGB );
img.createGraphics().drawImage(selectImg, 0, 0, null);
File final_image = new File("C:/Final.jpg");
ImageIO.write(img, "jpeg", final_image);
The idea of app is:
- Select an area of the image.
- Copy that image and paste in other file. ( when I pressed any button )
- The program will continue run until I press another button.
- Every image that I copy the program will paste it beside the last one.
I think I am near to the solution. Can any one help me to "connect the parts" ?
Start by taking a look at:
How to Write a Mouse Listener
How to Use Buttons, Check Boxes, and Radio Buttons
How to Write an Action Listeners
Performing Custom Painting
Writing/Saving an Image
You need to take the concepts you have and rework them into a coherent workable solution. That is, provide functionality between the areas you need (selecting a region and saving the file) so that they work cleanly together...
The following example takes a screenshot, allows you to select an area, click save and the file will be saved. The example checks to see how many files are already in the current directory and increments the count by 1 so you are not overwriting the existing files...
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScreenImage {
public static void main(String[] args) {
new ScreenImage();
}
public ScreenImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
try {
Robot robot = new Robot();
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane(screen));
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (AWTException exp) {
exp.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
private BufferedImage master;
public TestPane(BufferedImage image) {
this.master = image;
setLayout(new BorderLayout());
final ImagePane imagePane = new ImagePane(image);
add(new JScrollPane(imagePane));
JButton btnSave = new JButton("Save");
add(btnSave, BorderLayout.SOUTH);
btnSave.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
BufferedImage img = imagePane.getSubImage();
master = append(master, img);
File save = new File("Capture.png");
ImageIO.write(master, "png", save);
imagePane.clearSelection();
JOptionPane.showMessageDialog(TestPane.this, save.getName() + " was saved", "Saved", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(TestPane.this, "Failed to save capture", "Error", JOptionPane.ERROR_MESSAGE);
}
}
public BufferedImage append(BufferedImage master, BufferedImage sub) {
// Create a new image which can hold both background and the
// new image...
BufferedImage newImage = new BufferedImage(
master.getWidth() + sub.getWidth(),
Math.max(master.getHeight(), sub.getHeight()),
BufferedImage.TYPE_INT_ARGB);
// Get new image's Graphics context
Graphics2D g2d = newImage.createGraphics();
// Draw the old background
g2d.drawImage(master, 0, 0, null);
// Position and paint the new sub image...
int y = (newImage.getHeight() - sub.getHeight()) / 2;
g2d.drawImage(sub, master.getWidth(), y, null);
g2d.dispose();
return newImage;
}
});
}
}
public class ImagePane extends JPanel {
private BufferedImage background;
private Rectangle selection;
public ImagePane(BufferedImage img) {
background = img;
MouseAdapter ma = new MouseAdapter() {
private Point clickPoint;
#Override
public void mousePressed(MouseEvent e) {
clickPoint = e.getPoint();
}
#Override
public void mouseDragged(MouseEvent e) {
Point dragPoint = e.getPoint();
int x = Math.min(clickPoint.x, dragPoint.x);
int y = Math.min(clickPoint.y, dragPoint.y);
int width = Math.abs(clickPoint.x - dragPoint.x);
int height = Math.abs(clickPoint.y - dragPoint.y);
selection = new Rectangle(x, y, width, height);
repaint();
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
public void clearSelection() {
selection = null;
repaint();
}
public BufferedImage getSubImage() {
BufferedImage img = null;
if (selection != null) {
img = background.getSubimage(selection.x, selection.y, selection.width, selection.height);
}
return img;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(background.getWidth(), background.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;
g2d.drawImage(background, x, y, this);
if (selection != null) {
Color stroke = UIManager.getColor("List.selectionBackground");
Color fill = new Color(stroke.getRed(), stroke.getGreen(), stroke.getBlue(), 128);
g2d.setColor(fill);
g2d.fill(selection);
g2d.setColor(stroke);
g2d.draw(selection);
}
g2d.dispose();
}
}
}
So apart from rendering the selection the hardest part would be generating the resulting image...
Basically, this done by creating a new BufferedImage and painting the old image and the new, sub, image together.
public BufferedImage append(BufferedImage master, BufferedImage sub) {
// Create a new image which can hold both background and the
// new image...
BufferedImage newImage = new BufferedImage(
master.getWidth() + sub.getWidth(),
Math.max(master.getHeight(), sub.getHeight()),
BufferedImage.TYPE_INT_ARGB);
// Get new image's Graphics context
Graphics2D g2d = newImage.createGraphics();
// Draw the old background
g2d.drawImage(master, 0, 0, null);
// Position and paint the new sub image...
int y = (newImage.getHeight() - sub.getHeight()) / 2;
g2d.drawImage(sub, master.getWidth(), y, null);
g2d.dispose();
return newImage;
}
The example replaces the previous (master) image with the one created here, so it will constantly be appending new images to the end of it...
You need more listeners for button pressed and released.. some lines in the mouseMoved also better placed in mousePressed.
You would want to update your captureRect when you release the mouse (in mouseReleased method).
Then you just write it to the file. You may adjust other things according to your needs.
And for clarity maybe it's better to add a save button into your UI.
public class ScreenCaptureRectangle {
Rectangle captureRect;
Point start = new Point();
SimpleDateFormat sdf;
ScreenCaptureRectangle(final BufferedImage screen) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
final BufferedImage screenCopy = new BufferedImage(
screen.getWidth(),
screen.getHeight(),
screen.getType());
final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy));
JScrollPane screenScroll = new JScrollPane(screenLabel);
screenScroll.setPreferredSize(new Dimension(
(int) (screen.getWidth() / 3),
(int) (screen.getHeight() / 3)));
JPanel panel = new JPanel(new BorderLayout());
panel.add(screenScroll, BorderLayout.CENTER);
JButton btnSave = new JButton("SAVE");
btnSave.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
double w = captureRect.getWidth();
double h = captureRect.getHeight();
double x = captureRect.getX();
double y = captureRect.getY();
int W = (int) w;
int H = (int) h;
int X = (int) x;
int Y = (int) y;
BufferedImage selectImg = screen.getSubimage(X, Y, W, H);
try {
String fName = generateFileName();
if (fName != null) {
File f = new File(fName);
if (f.createNewFile()) {
ImageIO.write(selectImg, "jpg", f);
}
}
} catch (IOException ex) {
Logger.getLogger(ScreenCaptureRectangle.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
panel.add(btnSave, BorderLayout.AFTER_LAST_LINE);
final JLabel selectionLabel = new JLabel(
"Drag a rectangle in the screen shot!");
panel.add(selectionLabel, BorderLayout.SOUTH);
repaint(screen, screenCopy);
screenLabel.repaint();
screenLabel.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent me) {
Point end = me.getPoint();
captureRect = new Rectangle(start,
new Dimension(end.x - start.x, end.y - start.y));
repaint(screen, screenCopy);
screenLabel.repaint();
selectionLabel.setText("Rectangle: " + captureRect);
}
});
screenLabel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent me) {
start = me.getPoint();
repaint(screen, screenCopy);
selectionLabel.setText("Start Point: " + start);
screenLabel.repaint();
}
#Override
public void mouseReleased(MouseEvent me) {
int endX = me.getX();
int endY = me.getY();
if (endX > start.x && endY > start.y) {
captureRect = new Rectangle(start.x, start.y, endX-start.x, endY-start.y);
System.out.println("Rectangle of interest: " + captureRect);
}
}
});
JOptionPane.showMessageDialog(null, panel);
}
private String generateFileName() {
return new StringBuilder("screencrop_").append(sdf.format(new Date())).append(".jpg").toString();
}
public void repaint(BufferedImage orig, BufferedImage copy) {
Graphics2D g = copy.createGraphics();
g.drawImage(orig, 0, 0, null);
if (captureRect != null) {
g.setColor(Color.RED);
g.draw(captureRect);
g.setColor(new Color(255, 255, 255, 150));
g.fill(captureRect);
}
g.dispose();
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
final Dimension screenSize = Toolkit.getDefaultToolkit().
getScreenSize();
final BufferedImage screen = robot.createScreenCapture(
new Rectangle(screenSize));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ScreenCaptureRectangle(screen);
}
});
}
}

Moving a background image in Swing

hello im new in programming and we have a project.We created a simple racing game with a moving background but I'm stuck on my code and i don't know how to do it. i need a moving background when the game starts please somebody help me. I'm begging T_T
here is my code:
public class Game extends JFrame implements KeyListener, ActionListener {
Random s = new Random();
int x = 0, y = 50, a = 0, b = 250, f = 900, a1 = 0, b2 = 350, a2 = 0, b3 = 150;
int Move;
int value;
JLabel spriteLabel1 = new JLabel(new ImageIcon("ss.gif"));
JLabel spriteLabel2 = new JLabel(new ImageIcon("ss.gif"));
JLabel spriteLabel3 = new JLabel(new ImageIcon("ss.gif"));
JLabel spriteLabel4 = new JLabel(new ImageIcon("ss.gif"));
JLabel background = new JLabel(new ImageIcon("geren.png"));
Timer T1 = new Timer(5000, this);
Timer T = new Timer(5, this);
public static void main(String args[]) {
new Game();
}
public Game() {
Container c = getContentPane();
c.setLayout(null);
c.add(spriteLabel1);
c.add(spriteLabel2);
c.add(spriteLabel3);
c.add(spriteLabel4);
c.add(background);
background.setBounds(0, 0, 1024, 768);
addKeyListener(this);
setSize(1000, 750);
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
spriteLabel1.setBounds(x, y, 60, 1000);
spriteLabel2.setBounds(a, b, 60, 800);
spriteLabel3.setBounds(a1, b2, 60, 500);
spriteLabel4.setBounds(a2, b3, 60, 650);
}
public void keyPressed(KeyEvent e) {
String k = e.getKeyText(e.getKeyCode());
if (k.equals("D")) {
if (a != f) {
x = x + 15;
spriteLabel1.setIcon(new ImageIcon("ss.gif"));
repaint();
if (x > f) {
x = f;
spriteLabel1.setIcon(new ImageIcon("ss.gif"));
//JOptionPane.showMessageDialog(null,"Congratulations!!
//Sanji wins!","Result",JOptionPane.PLAIN_MESSAGE,
//new ImageIcon("evolve sanji.gif"));
//System.exit(0);
}
repaint();
}
}
T.stop();
}
if(k.equals (
"D"))
{
if (x != f) {
T.start();
Move = 3;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void actionPerformed(ActionEvent e) {
if (Move == 3) {
a = a + (s.nextInt(3));
a = a + value;
if (a > f) {
a = f;
}
spriteLabel2.setIcon(new ImageIcon("ss.gif"));
spriteLabel2.setBounds(a, b, 100, 800);
}
if (a == f) {
if (Move == 3) {
a1 = a1 + (s.nextInt(3));
a1 = a1 + value;
if (a1 > f) {
a1 = f;
}
spriteLabel3.setIcon(new ImageIcon("ss.gif"));
spriteLabel3.setBounds(a1, b2, 100, 500);
}
if (Move == 3) {
a2 = a2 + (s.nextInt(5));
a2 = a2 + value;
if (a2 > f) {
a2 = f;
}
spriteLabel4.setIcon(new ImageIcon("ss.gif"));
spriteLabel4.setBounds(a2, b3, 100, 650);
}
}
}
}
Here's the spoiler
Here's the meat
There a a few things I see you doing wrong:
Constantly creating new Images. Just use the same image.
I would, instead of using label, just paint an Image/BufferedImage onto the painting surface.
Forget two timers. You can make due with one. It's just how you manage your state.
Don't do any logic in the paint method. In your current case, since are not even painting anything, you don't even need it. In my example though I do paint the image.
Don't Paint on JFrame and override paint. Override paintComponent instead in a JPanel and add that panel to the frame.
Finally, the key ingredient, use the method (from Graphics) -
public abstract boolean drawImage(Image img,
int dx1,
int dy1,
int dx2,
int dy2,
int sx1,
int sy1,
int sx2,
int sy2,
ImageObserver observer)
You can get a better explanation about it in this post. Basically, the s points are the source image, so you can just move the sx1 and sx2 during the animation, and it will move the part of the image to be drawn at the d points of the painting surface.
If you don't know how to really do custom painting, I suggest you run through Performing Custom Painting
Here's the full example
(Note the image I used for the background was 2000x350)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class MovingBackgroundDemo {
public MovingBackgroundDemo() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new AnimatingPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class AnimatingPanel extends JPanel {
private static final int DIM_W = 350;
private static final int DIM_H = 350;
private static final int INCREMENT = 10;
private BufferedImage backgroundImage;
private Image runnerImage;
private int dx1, dy1, dx2, dy2;
private int srcx1, srcy1, srcx2, srcy2;
private int IMAGE_WIDTH;
public AnimatingPanel() {
initImages();
initImagePoints();
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
moveBackground();
repaint();
}
});
timer.start();
FlowLayout layout = (FlowLayout)getLayout();
layout.setHgap(0);
layout.setVgap(0);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(backgroundImage, dx1, dy1, dx2, dy2, srcx1, srcy1,
srcx2, srcy2, this);
g.drawImage(runnerImage, 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(350, 350);
}
private void initImagePoints() {
dx1 = 0;
dy1 = 0;
dx2 = DIM_W;
dy2 = DIM_H;
srcx1 = 0;
srcy1 = 0;
srcx2 = DIM_W;
srcy2 = DIM_H;
}
private void initImages() {
try {
runnerImage = new ImageIcon(getClass().getResource("runner.gif")).getImage();
backgroundImage = ImageIO.read(getClass().getResource(
"background.png"));
IMAGE_WIDTH = backgroundImage.getWidth();
System.out.println(IMAGE_WIDTH);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void moveBackground() {
if (srcx1 > IMAGE_WIDTH) {
srcx1 = 0 - DIM_W;
srcx2 = 0;
} else {
srcx1 += INCREMENT;
srcx2 += INCREMENT;
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MovingBackgroundDemo();
}
});
}
}

Convert a Graphics2D to an Image or BufferedImage

I have a little problem here.
I have an applet, where user can "draw" inside it. To do that, I use the java.awt.Graphics2D.
But, how can I do to save the user draw image as a JPEG image, or at least, convert it to a BufferedImage or something? I don't know how to do that.
Thanks.
Have them draw directly in a BufferedImage by way of it's Graphics2D object which you can get via getGraphics(). Then use ImageIO.write(...) to output the image to whatever file type you desire (and that's supported). The ImageIO API should help you with this: ImageIO API.
The other issue you'll have is where are they supposed to save the image once it has been drawn? On their own computer? If so and this is an applet program, then the applet will need to be "signed" in order for it to have the permission to write to disk. If you're unsure on this, check out Google, this article, or you may wish to write a new question for this issue alone.
Edit 1: code example
For example:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
#SuppressWarnings("serial")
public class DrawAndSaveImage extends JPanel {
private static final int BI_WIDTH = 600;
private static final int BI_HEIGHT = BI_WIDTH;
private static final Color LABEL_DRAW_COLOR = new Color(180, 180, 255);
private static final Stroke LABEL_DRAW_STROKE = new BasicStroke(1);
private static final Stroke BIMAGE_DRAW_STROKE = new BasicStroke(4);
private static final int COLOR_DIV = 5;
private BufferedImage bImage = new BufferedImage(BI_WIDTH, BI_HEIGHT,
BufferedImage.TYPE_INT_RGB);
private List<Point> pointList = new ArrayList<Point>();
private JLabel imageLabel;
private List<Color> colorList = new ArrayList<Color>();
private Random random = new Random();
public DrawAndSaveImage() {
Graphics2D g2d = bImage.createGraphics();
g2d.setBackground(Color.white);
g2d.clearRect(0, 0, BI_WIDTH, BI_HEIGHT);
g2d.dispose();
for (int r = 0; r < COLOR_DIV; r++) {
for (int g = 0; g < COLOR_DIV; g++) {
for (int b = 0; b < COLOR_DIV; b++) {
Color c = new Color((r * 255) / COLOR_DIV,
(g * 255) / COLOR_DIV, (b * 255) / COLOR_DIV);
colorList.add(c);
}
}
}
imageLabel = new JLabel(new ImageIcon(bImage)) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintInLabel(g);
}
};
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
imageLabel.addMouseListener(myMouseAdapter);
imageLabel.addMouseMotionListener(myMouseAdapter);
imageLabel.setBorder(BorderFactory.createEtchedBorder());
JButton saveImageBtn = new JButton("Save Image");
saveImageBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
saveImageActionPerformed();
}
});
JButton clearImageBtn = new JButton("Clear Image");
clearImageBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Graphics2D g2 = bImage.createGraphics();
g2.setBackground(Color.white);
g2.clearRect(0, 0, BI_WIDTH, BI_HEIGHT);
g2.dispose();
imageLabel.repaint();
}
});
JPanel btnPanel = new JPanel();
btnPanel.add(saveImageBtn);
btnPanel.add(clearImageBtn);
setLayout(new BorderLayout());
add(imageLabel, BorderLayout.CENTER);
add(btnPanel, BorderLayout.SOUTH);
}
private void saveImageActionPerformed() {
JFileChooser filechooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG Images", "jpg");
filechooser.setFileFilter(filter);
int result = filechooser.showSaveDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
File saveFile = filechooser.getSelectedFile();
try {
ImageIO.write(bImage, "jpg", saveFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void paintInLabel(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(LABEL_DRAW_COLOR);
g2d.setStroke(LABEL_DRAW_STROKE);
if (pointList.size() < 2) {
return;
}
for (int i = 1; i < pointList.size(); i++) {
int x1 = pointList.get(i - 1).x;
int y1 = pointList.get(i - 1).y;
int x2 = pointList.get(i).x;
int y2 = pointList.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
pointList.add(e.getPoint());
imageLabel.repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
Graphics2D g2d = bImage.createGraphics();
g2d.setColor(colorList.get(random.nextInt(colorList.size())));
g2d.setStroke(BIMAGE_DRAW_STROKE);
if (pointList.size() >= 2) {
for (int i = 1; i < pointList.size(); i++) {
int x1 = pointList.get(i - 1).x;
int y1 = pointList.get(i - 1).y;
int x2 = pointList.get(i).x;
int y2 = pointList.get(i).y;
g2d.drawLine(x1, y1, x2, y2);
}
}
g2d.dispose();
pointList.clear();
imageLabel.repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
pointList.add(e.getPoint());
imageLabel.repaint();
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("DrawAndSaveImage");
frame.getContentPane().add(new DrawAndSaveImage());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
I do it that way, and works very well:
BufferedImage awtImage = new BufferedImage(drawPanel.getWidth(), drawPanel.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = awtImage.getGraphics();
drawPanel.printAll(g);
try
{
String caminhoImagem = System.getProperty("user.home") + "\\temps\\assinatura.jpg";
FileOutputStream fos = new FileOutputStream(caminhoImagem);
JPEGImageEncoderImpl j = new JPEGImageEncoderImpl(fos);
j.encode(awtImage);
fos.close();
} catch(e) {..... }
That's all :)
Thanks everyone :)
Use the drawImage method provided by Graphics2D and write it using ImageIO
BufferedImage img;
g2dObject.drawImage(img, null, 0, 0);
ImageIO.write(img, "JPEG", new File("foo.jpg"));
Use the "drawOnImage" example from Custom Painting Approaches. Then to create the image of the panel you can use the Screen Image class.
If you'd like to draw JComponent's image onto BufferedImage (JApplet extends JComponent):
JComponent whatToDraw = ...;
BufferedImage img = new BufferedImage(whatToDraw.getWidth(),
whatToDraw.getHeight(), BufferedImage.TYPE_INT_RGB);
whatToDraw.printAll(img.getGraphics());
And to write its data to JPEG file:
ImageIO.write(img, "jpg", new File("something.jpg"));

Categories

Resources