java使用Graphics在图片上绘制形状

开发中遇到一个需求,就是在抓拍的图片上按照点位画出有效区域,并且区域有正选和反选,所以需要填充多边形内和多边形外。

花了些时间看源码找资料,搞出了个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结果图:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
分形树是一种常见的分形图形,可以使用JavaGraphics类进行绘制。下面是一个简单的示例代码: ```java import java.awt.*; import javax.swing.*; public class FractalTree extends JPanel { private int depth = 10; // 树的深度 private double angle = Math.PI / 4; // 树的分支角度 private double length = 100; // 树干长度 private double shrink = 0.7; // 子树干长度缩小比例 public FractalTree() { setBackground(Color.white); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); drawTree(g, getWidth() / 2, getHeight() - 50, length, -Math.PI / 2, depth); } private void drawTree(Graphics g, double x1, double y1, double len, double angle, int depth) { if (depth == 0) return; double x2 = x1 + len * Math.cos(angle); double y2 = y1 + len * Math.sin(angle); g.drawLine((int) x1, (int) y1, (int) x2, (int) y2); drawTree(g, x2, y2, len * shrink, angle + this.angle, depth - 1); drawTree(g, x2, y2, len * shrink, angle - this.angle, depth - 1); } public static void main(String[] args) { JFrame frame = new JFrame("Fractal Tree"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 500); FractalTree tree = new FractalTree(); frame.add(tree); frame.setVisible(true); } } ``` 在这个示例中,我们创建了一个继承自JPanel的FractalTree类,用于绘制分形树。在paintComponent方法中,我们调用drawTree方法绘制分形树。drawTree方法使用递归的方式绘制树的分支,直到达到指定的深度。每次绘制分支时,都会根据当前角度计算下一个点的坐标,并绘制一条直线。 在main方法中,我们创建一个JFrame,并将FractalTree实例添加到其中。运行程序后,将会显示一棵分形树。通过改变depth、angle、length和shrink等参数,可以绘制不同形状的分形树。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值