开发中遇到一个需求,就是在抓拍的图片上按照点位画出有效区域,并且区域有正选和反选,所以需要填充多边形内和多边形外。
花了些时间看源码找资料,搞出了个demo
1、图片上绘制多边形区域并填充颜色
/**
* 填充矩形(单色)
* @param fromFile
* @param x
* @param y
* @param toPath
*/
public static void fillPolygon(String fromFile, int[] x, int[] y, String toPath) {
try {
BufferedImage from = ImageIO.read(new File(fromFile));
Graphics2D g2d = from.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(255, 255, 255, 100)); //设置颜色
g2d.setStroke(new BasicStroke(5f)); //设置划线粗细
Polygon polygon = new Polygon(x, y, 4);
g2d.drawPolygon(polygon);
g2d.fillPolygon(polygon);
String toFile = toPath + System.currentTimeMillis() + ".jpg";
FileOutputStream out = new FileOutputStream(toFile);
ImageIO.write(from, "jpg", out);
out.close();
System.out.println("==fillPolygon==================" + toFile);
} catch (IOException e) {
e.printStackTrace();
}
}
2、图片上绘制多边形区域,反向填充颜色
/**
* 反向填充矩形(单色)
* @param fromFile
* @param x
* @param y
* @param toPath
*/
public static void reverseFillPolygon(String fromFile, int[] x, int[] y, String toPath) {
try {
BufferedImage img_from = ImageIO.read(new File(fromFile));
//1、绘制裁剪矩形
Polygon polygon = new Polygon(x, y, 4);
//设置裁剪后的背景色
Rectangle2D rectangle = new Rectangle(0,0,img_from.getWidth(),img_from.getHeight());
TexturePaint tPaint = new TexturePaint(img_from,rectangle);
BufferedImage img_clip = new BufferedImage(img_from.getWidth(), img_from.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d_clip = img_clip.createGraphics();
g2d_clip.setPaint(tPaint);
g2d_clip.fillPolygon(polygon);
g2d_clip.dispose();
//2、将裁剪后的原图整个填充背景色
Graphics2D g2d = img_from.createGraphics();
g2d.setColor(new Color(255, 255, 255, 150)); //设置颜色
g2d.fillRect(0, 0, img_from.getWidth(), img_from.getHeight()); //填充指定的矩形
//3、将裁剪的矩形绘制到原图
g2d.drawImage(img_clip, 0, 0, null);
g2d.dispose();
String toFile2 = toPath + System.currentTimeMillis() + ".jpg";
FileOutputStream out2 = new FileOutputStream(toFile2);
ImageIO.write(img_from, "jpg", out2);
out2.close();
System.out.println("==reverseFillPolygon==================" + toFile2);
} catch (IOException e) {
e.printStackTrace();
}
}
3、图片上绘制多边形区域,填充斜线
/**
* 填充矩形(斜线)
* @param fromFile
* @param x
* @param y
* @param toPath
*/
public static void fillPolygonWithLine(String fromFile, int[] x, int[] y, String toPath) {
try {
BufferedImage from = ImageIO.read(new File(fromFile));
Graphics2D g2d = from.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(255, 255, 255, 200)); //设置颜色
g2d.setStroke(new BasicStroke(1.5f)); //设置划线粗细
Polygon polygon = new Polygon(x, y, 4);
//裁切
g2d.setClip(polygon);
//取得多边形外接矩形
Rectangle rect = polygon.getBounds();
//绘制填充线i
for (int i = rect.y; i-rect.width < rect.y + rect.height; i = i + 6) {
Line2D line = new Line2D.Float(rect.x, i, (rect.x + rect.width), i-rect.width);
g2d.draw(line);
}
//绘制多边形
g2d.drawPolygon(polygon);
//输出绘制后的图片
String toFile = toPath + System.currentTimeMillis() + ".jpg";
FileOutputStream out = new FileOutputStream(toFile);
ImageIO.write(from, "jpg", out);
out.close();
System.out.println("==fillPolygonWithLine==================" + toFile);
} catch (IOException e) {
e.printStackTrace();
}
}
4、运行结果
public static void main(String[] args) {
String fromFile = "D:\\William\\Desktop" + File.separator + "draw\\44a64248a444_6_20230515191005_1.jpg";
String toPath = "D:\\William\\Desktop" + File.separator + "draw\\";
int[] xPoint = {474, 471, 963, 855};
int[] yPoint = {711, 996, 1005, 612};
fillPolygon(fromFile, xPoint, yPoint, toPath);
reverseFillPolygon(fromFile, xPoint, yPoint, toPath);
fillPolygonWithLine(fromFile, xPoint, yPoint, toPath);
}
原图:
fillPolygon结果图:
reverseFillPolygon结果图:
fillPolygonWithLine结果图: