JAVA版的画图工具
程序员文章站
2022-06-24 19:42:59
...
今天想实现在图片上画框,并得到各个顶点,就想用JAVA来实现载入图片,并在图片上画线,画框,选择删除操作。
做下来发现有几个问题要注意:
(1),如何用JPANEL做画板,并且载入大图片时,能够有滚动条。
(2),绘图如何保存前一步的操作,以及怎么把矩形打散成线。对图片形的进一步操作
以下是代码,在ECLIPSE中实现
DrawFrame.java
package org.lee.rag;
import java.awt.BasicStroke;
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.Rectangle;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JRadioButton;
public class DrawFrame extends JFrame {
private JPanel contentPane;
private ImagePanel imagePanel;
private BufferedImage image=null;
private Graphics g=null;
private int preX=-1;
private int preY=-1;
private int currentX=-1;
private int currentY=-1;
private boolean hlineFlag=false;
private boolean vlineFlag=false;
private boolean rectFlag=false;
private boolean modifyFlag=false;
private ButtonPanel bp=new ButtonPanel("形状",new String[]{"横线","竖线","矩形","修改"});
private List<LinkedPoint> lpList=new ArrayList<LinkedPoint>();
private List<Line> lineList=new ArrayList<Line>();
private Line currentLine=null;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DrawFrame frame = new DrawFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public DrawFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 710, 569);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.NORTH);
JButton openbtn = new JButton("open");
openbtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(rootPane);
if(returnVal == JFileChooser.APPROVE_OPTION) {
try {
BufferedImage bImage=ImageIO.read(chooser.getSelectedFile());
int width=bImage.getWidth();
int height=bImage.getHeight();
image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
imagePanel.setPreferredSize(new Dimension(width,height));
g=image.getGraphics();
g.drawImage(bImage,0,0,null);
imagePanel.repaint();
imagePanel.updateUI();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
panel.add(openbtn);
JButton delBtn = new JButton("del");
delBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(currentLine!=null){
lineList.remove(currentLine);
currentLine=null;
}
imagePanel.repaint();
}
});
panel.add(delBtn);
panel.add(bp);
imagePanel=new ImagePanel();
imagePanel.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
int x=e.getX();
int y=e.getY();
int srcY,srcX,destY,destX;
for(int i=0;i<lineList.size();i++){
Line line=lineList.get(i);
if(x==line.getSrcX()){
if(line.getSrcY()>line.getDestY()){
srcY=line.getSrcY();
destY=line.getDestY();
}
else{
srcY=line.getDestY();
destY=line.getSrcY();
}
if(y>=destY && y<=srcY){
currentLine=line;
}
}
if(y==line.getSrcY()){
if(line.getSrcX()>line.getDestX()){
srcX=line.getSrcX();
destX=line.getDestX();
}
else{
srcX=line.getDestX();
destX=line.getSrcX();
}
if(x>=destX && x<=srcX){
currentLine=line;
}
}
}
imagePanel.repaint();
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
currentLine=null;
if(bp.getSelection().equals("横线")){
hlineFlag=true;
}
if(bp.getSelection().equals("竖线")){
vlineFlag=true;
}
if(bp.getSelection().equals("矩形")){
rectFlag=true;
}
if(bp.getSelection().equals("修改")){
modifyFlag=true;
}
preX=e.getX();
preY=e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
if(hlineFlag || vlineFlag){
lineList.add(new Line(preX,preY,currentX,currentY));
LinkedPoint lp=new LinkedPoint(preX,preY);
lp.add(new LinkedPoint(currentX,currentY));
}
if(rectFlag){
lineList.add(new Line(preX,preY,currentX,preY));
lineList.add(new Line(currentX,preY,currentX,currentY));
lineList.add(new Line(preX,currentY,currentX,currentY));
lineList.add(new Line(preX,currentY,preX,preY));
LinkedPoint lp=new LinkedPoint(preX,preY);
lp.add(new LinkedPoint(preX,currentY));
lp.add(new LinkedPoint(currentX,preY));
lp.add(new LinkedPoint(currentX,currentY));
lpList.add(lp);
}
preX=-1;
preY=-1;
currentX=-1;
currentY=-1;
hlineFlag=false;
vlineFlag=false;
rectFlag=false;
modifyFlag=false;
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
});
imagePanel.addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
if(preX>0 && preY>0){
if(hlineFlag){
currentX=e.getX();
currentY=preY;
}
if(vlineFlag){
currentX=preX;
currentY=e.getY();
}
if(rectFlag){
currentX=e.getX();
currentY=e.getY();
}
imagePanel.repaint();
}
}
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
});
imagePanel.setSize(new Dimension(800,1000));
contentPane.add(new JScrollPane(imagePanel), BorderLayout.CENTER);
}
class ImagePanel extends JPanel{
@Override
public void paintComponent(Graphics g){
Graphics2D g2d=(Graphics2D) g.create();
g2d.clearRect(0,0,this.getWidth(), this.getHeight());
g2d.drawImage(image,0,0,null);
g2d.setStroke(new BasicStroke(4.0f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
g2d.setColor(Color.red);
int width=currentX-preX;
int height=currentY-preY;
if(rectFlag){
g2d.drawRect(preX, preY, width, height);
}
if(hlineFlag){
g2d.drawLine(preX, preY, currentX, currentY);
}
if(vlineFlag){
g2d.drawLine(preX, preY, currentX, currentY);
}
for(int i=0;i<lineList.size();i++){
Line line=lineList.get(i);
g2d.drawLine(line.getSrcX(), line.getSrcY(), line.getDestX(), line.getDestY());
}
//画点
if(currentLine!=null){
g2d.setColor(Color.black);
g2d.setStroke(new BasicStroke(1.0f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
g2d.drawOval(currentLine.getSrcX()-2, currentLine.getSrcY()-2, 4, 4);
g2d.drawOval(currentLine.getDestX()-2, currentLine.getDestY()-2, 4, 4);
}
g2d.dispose();
}
}
class ButtonPanel extends JPanel{
private ButtonGroup group;
public ButtonPanel(String title,String[] option){
setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));
setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
group=new ButtonGroup();
for(int i=0;i<option.length;i++){
JRadioButton b=new JRadioButton(option[i]);
add(b);
group.add(b);
b.setActionCommand(option[i]);
b.setSelected(i==0);
}
}
public String getSelection(){
return group.getSelection().getActionCommand();
}
}
}
Line.java
package org.lee.rag;
public class Line {
private int srcX;
private int srcY;
private int destX;
private int destY;
public Line(){
}
public Line(int srcX,
int srcY,
int destX,
int destY){
this.srcX=srcX;
this.srcY=srcY;
this.destX=destX;
this.destY=destY;
}
public int getSrcX() {
return srcX;
}
public void setSrcX(int srcX) {
this.srcX = srcX;
}
public int getSrcY() {
return srcY;
}
public void setSrcY(int srcY) {
this.srcY = srcY;
}
public int getDestX() {
return destX;
}
public void setDestX(int destX) {
this.destX = destX;
}
public int getDestY() {
return destY;
}
public void setDestY(int destY) {
this.destY = destY;
}
}
LinkedPoint.java
package org.lee.rag;
public class LinkedPoint {
private int x;
private int y;
private LinkedPoint currentPoint=null;
//后一个节点
private LinkedPoint nextPoint=null;
public LinkedPoint(){
init();
}
public LinkedPoint(int x,int y){
this.x=x;
this.y=y;
init();
}
private void init(){
currentPoint=this;
}
public boolean hasNext(){
return (nextPoint==null) ? false : true;
}
public void add(LinkedPoint point){
if(currentPoint.hasNext()){
currentPoint=currentPoint.getNextPoint();
}
currentPoint.setNextPoint(point);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public LinkedPoint getNextPoint() {
return nextPoint;
}
public void setNextPoint(LinkedPoint nextPoint) {
this.nextPoint = nextPoint;
}
}