java 可变框 抠图 切割 界面 虚线框

这是一个使用Java实现的可交互式图像选择和切割工具。通过Canvas类,用户可以进行矩形和三角形的选择,并提供了调整大小和移动的选项。程序支持鼠标事件监听,允许用户在图像上画出虚线框进行选择,并可以保存处理后的图像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >







//canvas 类,用于抠图区分前景
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.sxk.Watershed;

public class SelectableCanvas3 extends Canvas {

private static final long serialVersionUID = -7159915510292362753L;

boolean selecting;// 是否正在拖拽矩形
int x, y;// 矩形原点坐标

PointRectangle selection;// 当前绘制的矩形

Triangle1 triangle; // 绘制三角形

Image image;// 载入鞋子模型图片
BufferedImage bi;// 缓存图片用来存。
String fileName = "0.jpg";
int activeHandle = -1;// 激活的Resize手柄
int activeHandleTriangle = -1;// 激活的Triangle Resize手柄

Rectangle[] handles = new Rectangle[9];// 8个Resize手柄

Rectangle[] triangleHandles = new Rectangle[4];// 3个Resize手柄 三角形的三个手柄

public SelectableCanvas3() {

ImageIcon icon = new ImageIcon("shoesModel.png");
image = icon.getImage();

this.setSize(600, 500);
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (selecting || activeHandle >= 0) {
wipeSelection();
confirmSelection(selection);
selecting = false;
activeHandle = -1;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}

@Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
});

addMouseMotionListener(new MouseMotionAdapter() {

public void mouseMoved(MouseEvent e) {
for (int i = 0; i < handles.length; i++) {
if (handles[i] != null
&& handles[i].contains(e.getX(), e.getY())) {
activeHandle = i;
switch (i) {
case 0:
case 4:
setCursor(Cursor
.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
break;
case 1:
case 5:
setCursor(Cursor
.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
break;
case 2:
case 6:
setCursor(Cursor
.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
break;
case 3:
case 7:
setCursor(Cursor
.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
break;
case 8:
setCursor(Cursor
.getPredefinedCursor(Cursor.MOVE_CURSOR));
break;
}
return;
}
}
activeHandle = -1;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

//

for (int i = 0; i < triangleHandles.length; i++) {
if (triangleHandles[i] != null
&& triangleHandles[i].contains(e.getX(), e.getY())) {
activeHandleTriangle = i;
switch (i) {
case 0:
setCursor(Cursor
.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
break;
case 1:
setCursor(Cursor
.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
break;
case 2:
setCursor(Cursor
.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
break;
case 3:
setCursor(Cursor
.getPredefinedCursor(Cursor.MOVE_CURSOR));
break;
}
return;
}
}
activeHandleTriangle = -1;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

}

public void mouseDragged(MouseEvent e) {
if (selection != null)
wipeSelection();
if (activeHandle >= 0) {
switch (activeHandle) {
case 0:
selection = new PointRectangle(e.getX(), e.getY(),
selection.x2, selection.y2);
break;
case 1:
selection = new PointRectangle(selection.x1, e.getY(),
selection.x2, selection.y2);
break;
case 2:
selection = new PointRectangle(selection.x1, e.getY(),
e.getX(), selection.y2);
break;
case 3:
selection = new PointRectangle(selection.x1,
selection.y1, e.getX(), selection.y2);
break;
case 4:
selection = new PointRectangle(selection.x1,
selection.y1, e.getX(), e.getY());
break;
case 5:
selection = new PointRectangle(selection.x1,
selection.y1, selection.x2, e.getY());
break;
case 6:
selection = new PointRectangle(e.getX(), selection.y1,
selection.x2, e.getY());
break;
case 7:
selection = new PointRectangle(e.getX(), selection.y1,
selection.x2, selection.y2);
break;
case 8:
selection = new PointRectangle(
selection.x1
+ e.getX()
- (selection.x1 + (selection.x2 - selection.x1) / 2),
selection.y1
+ e.getY()
- (selection.y1 + (selection.y2 - selection.y1) / 2),
selection.x2
+ e.getX()
- (selection.x1 + (selection.x2 - selection.x1) / 2),
selection.y2
+ e.getY()
- (selection.y1 + (selection.y2 - selection.y1) / 2));
break;
}

// drawSelection(selection);
repaint();
}
/*
* else { selection = new PointRectangle(x, y, e.getX(),
* e.getY()); // selection = new PointRectangle(100, 100, 200,
* 200); repaint(); // drawSelection(selection); //
* drawSelection(selection); selecting = true;
* setCursor(Cursor.getPredefinedCursor
* (Cursor.CROSSHAIR_CURSOR)); }
*/

if (activeHandleTriangle >= 0) {
switch (activeHandleTriangle) {
case 0:
triangle = new Triangle1(new Point(e.getPoint()),
triangle.getP2(), triangle.getP3());

break;
case 1:
triangle = new Triangle1(triangle.getP1(), new Point(
e.getPoint()), triangle.getP3());

break;
case 2:
triangle = new Triangle1(triangle.getP1(),
triangle.getP2(), new Point(e.getPoint()));
break;
case 3:
triangle = new Triangle1(
new Point(
(triangle.getP1().x + e.getX() - (triangle
.getP3().x + (triangle.getP2().x - triangle
.getP3().x) / 2)),
triangle.getP1().y
+ e.getY()
- (triangle.getP1().y + (triangle
.getP2().y - triangle
.getP1().y) / 2)),
new Point(
(triangle.getP2().x + e.getX() - (triangle
.getP3().x + (triangle.getP2().x - triangle
.getP3().x) / 2)),
triangle.getP2().y
+ e.getY()
- (triangle.getP1().y + (triangle
.getP2().y - triangle
.getP1().y) / 2)),
new Point(
(triangle.getP3().x + e.getX() - (triangle
.getP3().x + (triangle.getP2().x - triangle
.getP3().x) / 2)),
triangle.getP3().y
+ e.getY()
- (triangle.getP1().y + (triangle
.getP2().y - triangle
.getP1().y) / 2)));
break;
}

// drawSelection(selection);
repaint();
}

}

});

selection = new PointRectangle(100, 100, 400, 300);

triangle = new Triangle1(new Point(350, 140), new Point(350, 270),
new Point(150, 270));

}

// 清除选择的矩形
public void clearSelection() {
selection = null;
selecting = false;
activeHandle = -1;
for (int i = 0; i < handles.length; i++)
handles[i] = null;
}

// 清除上次的绘制的矩形
private void wipeSelection() {
Graphics2D graphics = (Graphics2D) this.getGraphics().create();// 初始化绘图上下文
// 定义擦除区域
Area area = new Area(new Rectangle(selection.x, selection.y,
selection.width + 1, selection.height + 1));
area.subtract(new Area(new Rectangle(selection.x + 1, selection.y + 1,
selection.width - 1, selection.height - 1)));
area.add(new Area(new Rectangle(selection.x - 2, selection.y - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x + selection.width / 2 - 2,
selection.y - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x + selection.width - 2,
selection.y - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x + selection.width - 2,
selection.y + selection.height / 2 - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x + selection.width - 2,
selection.y + selection.height - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x + selection.width / 2 - 2,
selection.y + selection.height - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x - 2, selection.y
+ selection.height - 2, 5, 5)));
area.add(new Area(new Rectangle(selection.x - 2, selection.y
+ selection.height / 2 - 2, 5, 5)));
graphics.setClip(area);// 应用擦除区域
update(graphics);// 用背景擦除
}

// 画虚线矩形
public void drawSelection(Rectangle selection) {
Graphics2D graphics = (Graphics2D) getGraphics().create();// 初始化绘图上下文
graphics.setPaint(Color.WHITE);// 设置边框颜色
graphics.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1f, new float[] { 5 }, 0));// 设置边框笔触
graphics.draw(selection);// 绘制选择边框
}

// 画带手柄的矩形
public void confirmSelection(Rectangle selection) {
this.selection = new PointRectangle(selection);
Graphics2D graphics = (Graphics2D) getGraphics();// 绘图上下文
if (selection.isEmpty()) {
clearSelection();
return;
}
graphics.setStroke(new BasicStroke(1));// 设置选择框底色笔触
graphics.setPaint(Color.BLUE);// 设置边框底色颜色
graphics.draw(selection);// 绘制选择边框底色
graphics.setPaint(Color.WHITE);// 设置边框颜色
graphics.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1f, new float[] { 5 }, 0));// 设置边框笔触
graphics.draw(selection);// 绘制选择边框
// 定义手柄
handles[0] = new Rectangle(selection.x - 2, selection.y - 2, 4, 4);
handles[1] = new Rectangle(selection.x + selection.width / 2 - 2,
selection.y - 2, 4, 4);
handles[2] = new Rectangle(selection.x + selection.width - 2,
selection.y - 2, 4, 4);
handles[3] = new Rectangle(selection.x + selection.width - 2,
selection.y + selection.height / 2 - 2, 4, 4);
handles[4] = new Rectangle(selection.x + selection.width - 2,
selection.y + selection.height - 2, 4, 4);
handles[5] = new Rectangle(selection.x + selection.width / 2 - 2,
selection.y + selection.height - 2, 4, 4);
handles[6] = new Rectangle(selection.x - 2, selection.y
+ selection.height - 2, 4, 4);
handles[7] = new Rectangle(selection.x - 2, selection.y
+ selection.height / 2 - 2, 4, 4);
graphics.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 1f));// 设置填充不透明
graphics.setPaint(Color.WHITE);// 设置手柄填充颜色
// 填充手柄
for (Rectangle handle : handles)
graphics.fill(handle);
graphics.setPaint(Color.BLACK);// 设置手柄边框颜色
graphics.setStroke(new BasicStroke(1f));// 设置实线笔触
// 绘制手柄边框
for (Rectangle handle : handles)
graphics.draw(handle);
}

// 返回当前有效的矩形
public Rectangle getSelection() {
return selection;
}

public void paint(Graphics g) {
super.paint(g);

ImageIcon icon = new ImageIcon(fileName);
// System.out.println(fileName);
Image image1 = icon.getImage();
g.drawImage(image1, 0, 0, 600, 500, this);

System.out.println("repaint");
Graphics2D graphics = (Graphics2D) g;
// Graphics2D graphics = (Graphics2D)bi.getGraphics();// 初始化绘图上下文
// bi.getGraphics()
graphics.setPaint(Color.WHITE);// 设置边框颜色
graphics.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1f, new float[] { 5 }, 0));// 设置边框笔触
graphics.draw(selection);// 绘制选择边框
// g.drawRect(selection.x, selection.y, selection.width,
// selection.height);

// 绘制鞋子模型
// graphics.drawImage(image,selection.x+10, selection.y+10,
// (selection.x2-selection.x1)-20, (selection.y2-selection.y1)-20,
// this);
// 绘制三角形边框

// graphics.
triangle.draw(graphics);
// my_saved_panel;
// test.jpg
this.selection = new PointRectangle(selection);
// Graphics2D graphics = (Graphics2D) getGraphics();// 绘图上下文
if (selection.isEmpty()) {
clearSelection();
return;
}
graphics.setStroke(new BasicStroke(1));// 设置选择框底色笔触
graphics.setPaint(Color.BLUE);// 设置边框底色颜色
graphics.draw(selection);// 绘制选择边框底色

graphics.setStroke(new BasicStroke(3));// 设置选择框底色笔触
graphics.setPaint(Color.RED);// 设置边框底色颜色
triangle.draw(graphics);

graphics.setPaint(Color.WHITE);// 设置边框颜色
graphics.setStroke(new BasicStroke(3, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 1f, new float[] { 5 }, 0));// 设置边框笔触
graphics.draw(selection);// 绘制选择边框

triangle.draw(graphics);

// 定义手柄
handles[0] = new Rectangle(selection.x - 2, selection.y - 2, 4, 4);
handles[1] = new Rectangle(selection.x + selection.width / 2 - 2,
selection.y - 2, 4, 4);
handles[2] = new Rectangle(selection.x + selection.width - 2,
selection.y - 2, 4, 4);
handles[3] = new Rectangle(selection.x + selection.width - 2,
selection.y + selection.height / 2 - 2, 4, 4);
handles[4] = new Rectangle(selection.x + selection.width - 2,
selection.y + selection.height - 2, 4, 4);
handles[5] = new Rectangle(selection.x + selection.width / 2 - 2,
selection.y + selection.height - 2, 4, 4);
handles[6] = new Rectangle(selection.x - 2, selection.y
+ selection.height - 2, 4, 4);
handles[7] = new Rectangle(selection.x - 2, selection.y
+ selection.height / 2 - 2, 4, 4);
handles[8] = new Rectangle(selection.x + (selection.x2 - selection.x1)
/ 2 - 2, selection.y + (selection.y2 - selection.y1) / 2 - 2,
4, 4);
// 定义三角形手柄

triangleHandles[0] = new Rectangle(triangle.getP1().x - 2,
triangle.getP1().y - 2, 4, 4);
triangleHandles[1] = new Rectangle(triangle.getP2().x - 2,
triangle.getP2().y - 2, 4, 4);
triangleHandles[2] = new Rectangle(triangle.getP3().x - 2,
triangle.getP3().y - 2, 4, 4);
triangleHandles[3] = new Rectangle(triangle.getP3().x
+ (triangle.getP2().x - triangle.getP3().x) / 2 - 2,
triangle.getP1().y + (triangle.getP2().y - triangle.getP1().y)
/ 2 - 2, 4, 4);

graphics.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 1f));// 设置填充不透明
graphics.setPaint(Color.WHITE);// 设置手柄填充颜色
// 填充手柄
for (Rectangle handle : handles)
graphics.fill(handle);
graphics.setPaint(Color.BLACK);// 设置手柄边框颜色
graphics.setStroke(new BasicStroke(1f));// 设置实线笔触

// 填充三角形手柄
for (Rectangle handle : triangleHandles)
graphics.fill(handle);
graphics.setPaint(Color.BLACK);// 设置手柄边框颜色
graphics.setStroke(new BasicStroke(1f));// 设置实线笔触

// 绘制手柄边框
for (Rectangle handle : handles)
graphics.draw(handle);

// 绘制三角形手柄边框
for (Rectangle handle : triangleHandles)
graphics.draw(handle);

// g.drawImage(bi,0,0,this);

}

public void saveImage(String fileName) {
bi = new BufferedImage(600, 500, BufferedImage.TYPE_INT_RGB);
Graphics2D biGraphics = (Graphics2D) bi.getGraphics();
// biGraphics.setBackground(Color.WHITE);
biGraphics.setPaint(Color.WHITE);
biGraphics.setStroke(new BasicStroke(3));
biGraphics.draw(selection);
triangle.draw(biGraphics);

try {
ImageIO.write(bi, "jpg", new File(fileName + ".jpg"));

} catch (Exception e) {
e.printStackTrace();
}
}

public void roadImage(String fileName) {

try {
this.fileName = fileName;
repaint();
} catch (Exception e) {
e.printStackTrace();
}
}

public void process(String filepath) {
String linepath = fileName;
String dstpath = "C:\\Users\\Administrator\\Desktop\\des.jpg";
Watershed.Process(linepath, filepath + ".jpg", dstpath);
System.out.println(filepath);
System.out.println(linepath);
System.out.println(dstpath);
}

}

//界面类函数,程序运行的主函数
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FileDialog;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ScreenWindow extends JFrame implements ActionListener {

/**
* @param args
* 
* 
* 
* 
*/
private static final long serialVersionUID = -1;

MenuBar menuBar = new MenuBar();
Menu file = new Menu("File"), edit = new Menu("Edit"), help = new Menu(
"Help");

MenuItem[] menuItem = { new MenuItem("New"), new MenuItem("Open"),
new MenuItem("Save"), new MenuItem("Exit"),
new MenuItem("Select All"), new MenuItem("Copy"),
new MenuItem("Cut"), new MenuItem("Paste"), new MenuItem("Help") };

String fileName = "NoName";
Toolkit toolKit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolKit.getSystemClipboard();

// opne and close message dialogs
private FileDialog openFileDialog = new FileDialog(this, "Open File",
FileDialog.LOAD);
private FileDialog saveFileDialog = new FileDialog(this, "Save File",
FileDialog.SAVE);
SelectableCanvas3 canvas;
Image image;
JPanel panel1;
JLabel jl;

public ScreenWindow() {
// this.setUndecorated(true); //去掉窗口装饰
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// SelectableCanvas2 aa = new SelectableCanvas2();
canvas = new SelectableCanvas3();
// aa.drawSelection(selection);
// this.add(aa);
panel1 = new JPanel();
// jl = new JLabel();
// jl.setSize(600, 500);
// this.add(panel1);

// panel1.add(jl);
// panel1.add(canvas);
this.setSize(650, 580);
this.add(canvas);
this.setVisible(true);
// selection = new PointRectangle(100, 100, 200, 200);

this.setResizable(false);
// this.setExtendedState(JFrame.MAXIMIZED_BOTH); // 窗口最大化
// aa.drawSelection(selection);
// aa.confirmSelection(selection);
System.out.println("hello ");

setMenuBar(menuBar);
menuBar.add(file);
menuBar.add(edit);
menuBar.add(help);
for (int i = 0; i < 4; i++) {
file.add(menuItem[i]);
edit.add(menuItem[i + 4]);
}
help.add(menuItem[8]);

addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
e.getWindow().dispose();
System.exit(0);
}
});

// add actionListener
for (int i = 0; i < menuItem.length; i++) {
menuItem[i].addActionListener(this);
}

}

public static void main(String[] args) {
// TODO Auto-generated method stub
new ScreenWindow();
}

public void actionPerformed(ActionEvent e) {
// TODO: Add your code here
Object eventSource = e.getSource();

if (eventSource == menuItem[0])// newItem
{
System.out.println("dipose picture");

}

else if (eventSource == menuItem[1])// OpenItem
{
openFileDialog.show();
fileName = openFileDialog.getDirectory() + openFileDialog.getFile();
if (fileName != null) {
openFile(fileName);
}
}

else if (eventSource == menuItem[2])// SaveItem
{
saveFileDialog.show();
fileName = saveFileDialog.getDirectory() + saveFileDialog.getFile();
if (fileName != null) {
writeFile(fileName);
System.out.println("save file");
canvas.process(fileName);
}
}

else if (eventSource == menuItem[3])// exitItem
{
System.exit(0);
}

else if (eventSource == menuItem[4])// Select All
{

} else if (eventSource == menuItem[5])// copy
{

}

else if (eventSource == menuItem[6])// cut
{

}

else if (eventSource == menuItem[7])// Paste
{
Transferable contents = clipboard.getContents(this);
if (contents == null)
return;
String text;
text = "";
try {
text = (String) contents
.getTransferData(DataFlavor.stringFlavor);

} catch (Exception ex) {
}

} else if (eventSource == menuItem[8]) {
// JOptionPane.showMessageDialog(null,"This is a MiniEdit.");
}

}

// Read file
public void openFile(String fileName) {
try {

// jl.setIcon(icon);
// jl = new JLabel(icon);
// jl.setSize(600, 500);
// this.add(panel1);
// panel1.add(jl);
// this.setBackground(Color.WHITE);
// this.setIconImage(image);
canvas.roadImage(fileName);

// 构造目标图片
// BufferedImage tag = new BufferedImage(600, 500,
// BufferedImage.TYPE_INT_RGB);

// 根据需求画出目标图片 方式1

// repaint();

System.out.println("read picture");
// repaint();
} catch (Exception e) {
System.out.println("Error read picture!");
}
}

// write file
public void writeFile(String fileName) {
try {
canvas.saveImage(fileName);
System.out.println("file saved");
} catch (Exception e) {
System.out.println("Error closing file!");
}
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值