java 中给预览图添加测量工具

最近碰到的给预览图加测量工具,测量图之间点与点的距离。最后实现的效果如下:

添加的方法如下:

首先新建一个测量工具的类(基本类):

public class MeasuringLine {

    Point2D startPoint;//第一个点
    Point2D endPoint;
    Point2D MiddlePoint; // 拖拽过程中的点,可以显示拖拽的痕迹
    String strdistance;
    double scale = 1;

    private BasicStroke lineStroke = new BasicStroke(1.0f);;

    public String getStrdistance() {
        return strdistance;
    }

    public MeasuringLine(Point2D startPos, Point2D endPos, double d) {
        startPoint = startPos;
        endPoint = endPos;
        this.scale = d;
        MeasuringDistance();

    }

    public MeasuringLine(Point2D startPos, double scale) {
        startPoint = startPos;
        this.scale = scale;
    }

    public void MeasuringDistance() {
        double x, y;
        x = startPoint.getX() / scale; // 页面可以缩放,这个时候需要计算真实的坐标
        y = startPoint.getY() / scale;
        startPoint = new Point2D.Double(x, y);

        x = endPoint.getX() / scale;
        y = endPoint.getY() / scale;
        endPoint = new Point2D.Double(x, y);

        x = (startPoint.getX() + endPoint.getX()) / 2;
        y = (int) ((startPoint.getY() + endPoint.getY()) / 2);
        MiddlePoint = new Point2D.Double(x, y);
        double distance = Point2D.distance(startPoint.getX(),
                startPoint.getY(), endPoint.getX(), endPoint.getY());
        int unitType = SystemParam.getInstance().getUnitType(); 
        distance = (float) Unit.parseToDisplayData2(unitType,
                String.valueOf(distance)); // 一般鼠标获取的点都是磅值,需要进行转换,这里换成mm值
        DecimalFormat decimalFormat = new DecimalFormat(".00");// 构造方法的字符格式这里如果小数不足2位,会以0补足.
        String p = decimalFormat.format(distance);
        strdistance = p + "mm";
    }

    public Point2D getStartPoint() {
        return startPoint;
    }

    public Point2D getEndPoint() {
        return endPoint;
    }

    public Point2D getMiddlePoint() {
        return MiddlePoint;
    }

    // 绘制图像
    public void paint(Graphics2D g2d, double x1, double y1, double x2, double y2) {
        Line2D.Double line2D = null;
        Arrow.Attributes arrowAttributes = null;
        line2D = new Line2D.Double(x1, y1, x2, y2);
        arrowAttributes = new Arrow.Attributes();   // 绘制的箭头
        arrowAttributes.angle = 30;
        arrowAttributes.height = 10;
        drawLineArrowDirectionAll(g2d, arrowAttributes, line2D);
    }

    private void drawLineArrowDirectionAll(Graphics2D g2d,
            Arrow.Attributes arrowAttributes, Line2D.Double line2D) {
        drawLine(g2d, line2D);
        drawArrow(g2d, arrowAttributes, line2D.getP1(), line2D.getP2());
        drawArrow(g2d, arrowAttributes, line2D.getP2(), line2D.getP1());
    }

    private void drawLine(Graphics2D g2d, Line2D.Double line2D) {
        g2d.setColor(Color.red);
        g2d.setStroke(lineStroke);
        g2d.draw(line2D);
    }

    private void drawArrow(Graphics2D g2d, Arrow.Attributes arrowAttributes,
            Point2D point1, Point2D point2) {
        // 获取Arrow实例
        Arrow arrow = getArrow(arrowAttributes, point1, point2);

        // 构建GeneralPath
        GeneralPath arrow2D = new GeneralPath();
        arrow2D.moveTo(arrow.point1.x, arrow.point1.y);
        arrow2D.lineTo(arrow.point2.x, arrow.point2.y);
        arrow2D.lineTo(arrow.point3.x, arrow.point3.y);
        arrow2D.closePath();

        // 绘制
        g2d.setColor(arrow.attributes.color);
        g2d.fill(arrow2D);
    }

    private Arrow getArrow(Arrow.Attributes arrowAttributes, Point2D point1,
            Point2D point2) {
        Arrow arrow = new Arrow(arrowAttributes);

        // 计算斜边
        double hypotenuse = arrow.attributes.height
                / Math.cos(Math.toRadians(arrow.attributes.angle / 2));

        // 计算当前线所在的象限
        int quadrant = -1;
        if (point1.getX() > point2.getX() && point1.getY() < point2.getY()) {  // 判断测量的点是否超过了页面的尺寸
            quadrant = 1;
        } else if (point1.getX() < point2.getX()
                && point1.getY() < point2.getY()) {
            quadrant = 2;
        } else if (point1.getX() < point2.getX()
                && point1.getY() > point2.getY()) {
            quadrant = 3;
        } else if (point1.getX() > point2.getX()
                && point1.getY() > point2.getY()) {
            quadrant = 4;
        }

        // 计算线的夹角
        double linAngle = getLineAngle(point1.getX(), point1.getY(),
                point2.getX(), point2.getY());
        if (Double.isNaN(linAngle)) {
            // 线与x轴垂直
            if (point1.getX() == point2.getX()) {
                if (point1.getY() < point2.getY()) {
                    linAngle = 90;
                } else {
                    linAngle = 270;
                }
                quadrant = 2;
            }
        }
        // 线与y轴垂直
        else if (linAngle == 0) {
            if (point1.getY() == point2.getY()) {
                if (point1.getX() < point2.getX()) {
                    linAngle = 0;
                } else {
                    linAngle = 180;
                }
                quadrant = 2;
            }
        }

        // 上侧一半箭头
        double xAngle = linAngle - arrow.attributes.angle / 2; // 与x轴夹角
        double py0 = hypotenuse * Math.sin(Math.toRadians(xAngle)); // 计算y方向增量
        double px0 = hypotenuse * Math.cos(Math.toRadians(xAngle)); // 计算x方向增量

        // 下侧一半箭头
        double yAngle = 90 - linAngle - arrow.attributes.angle / 2; // 与y轴夹角
        double px1 = hypotenuse * Math.sin(Math.toRadians(yAngle));
        double py1 = hypotenuse * Math.cos(Math.toRadians(yAngle));

        // 第一象限
        if (quadrant == 1) {
            px0 = -px0;
            px1 = -px1;

        } else if (quadrant == 2) {
            // do nothing
        } else if (quadrant == 3) {
            py0 = -py0;
            py1 = -py1;

        } else if (quadrant == 4) {
            py0 = -py0;
            px0 = -px0;

            px1 = -px1;
            py1 = -py1;
        }

        // build
        arrow.point1 = new Point2D.Double();
        arrow.point1.x = point1.getX();
        arrow.point1.y = point1.getY();

        arrow.point2 = new Point2D.Double();
        arrow.point2.x = point1.getX() + px0;
        arrow.point2.y = point1.getY() + py0;

        arrow.point3 = new Point2D.Double();
        arrow.point3.x = point1.getX() + px1;
        arrow.point3.y = point1.getY() + py1;

        return arrow;
    }

    protected double getLineAngle(double x1, double y1, double x2, double y2) {
        double k1 = (y2 - y1) / (x2 - x1);
        double k2 = 0;
        return Math.abs(Math.toDegrees(Math.atan((k2 - k1) / (1 + k1 * k2))));
    }

    public static class Arrow {
        Attributes attributes;
        Point2D.Double point1;
        Point2D.Double point2;
        Point2D.Double point3;

        public Arrow(Attributes attributes) {
            this.attributes = attributes;
        }

        public static class Attributes {
            double height; // 箭头的高度
            double angle; // 箭头角度
            Color color; // 箭头颜色

            public Attributes() {
                this.height = 20;
                this.angle = 30;
                this.color = Color.RED;
            }
        }
    }

}
2. 添加鼠标监听的类:

public class MeasuringTool implements MouseListener {
    int flag; // flag=1代表Mouse Moved,flag=2代表Mouse Dragged
    int x = 0;
    int y = 0;
    double startx;
    double starty;
    double endx;// 起始坐标与终点坐标
    double endy;
    MeasuringLine Currentline;
    ImagePane mainPanel;   // 呈现的那个面板,最终我们是要把箭头画在这个页面上
    Graphics g;
    boolean selectLine = false;
    /** 处理鼠标拖动的事件处理器 */
    private MouseInputListener dragHandler = new DragHandler(); 

    public MeasuringTool(ImagePane imagePanel) {
        mainPanel = imagePanel;
        mainPanel.addMouseListener(this);
        mainPanel.addMouseMotionListener(dragHandler);
    }

    @Override
    /* 由mousePressed(),mouseReleased()取得鼠标拖曳的开始与结束坐标 */
    public void mousePressed(MouseEvent e) {

        Point2D pos = mainPanel.getMousePosition();
        startx = pos.getX();
        starty = pos.getY();
        if (startx > mainPanel.getImageWidth()
                || starty > mainPanel.getImageHeight()) {
            return;
        } else {
            Currentline = new MeasuringLine(pos, mainPanel.getScale());
        }

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (Currentline != null) {
            Point2D pos = mainPanel.getMousePosition();
            if (pos == null)
                return;
            endx = pos.getX();
            endy = pos.getY();
            if (endx > mainPanel.getImageWidth())
                endx = mainPanel.getImageWidth();
            if (endy > mainPanel.getImageHeight())
                endy = mainPanel.getImageHeight();
            Currentline.endPoint = new Point2D.Double(endx, endy);
            // mainPanel.addMeasuringLine(line1);
            mainPanel.repaint();
            Currentline = null;
        }

    }

    public void mouseDragged(MouseEvent e) {
        Point2D pos = mainPanel.getMousePosition();
        double x = pos.getX();
        double y = pos.getY();
        if (x > mainPanel.getImageWidth())
            x = mainPanel.getImageWidth();
        if (y > mainPanel.getImageHeight())
            y = mainPanel.getImageHeight();
        Currentline.endPoint = new Point2D.Double(x, y);
        mainPanel.addMeasuringLine(Currentline);
        mainPanel.repaint();
    }

    public void mouseClicked(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    /** 处理鼠标拖动的事件处理器 */
    private class DragHandler extends MouseInputAdapter {
        private int anchorX, anchorY;

        @Override
        public void mouseDragged(MouseEvent e) {
            Point2D pos = mainPanel.getMousePosition();
            if (pos == null)
                return;
            else {
                double x = pos.getX();
                double y = pos.getY();
                if (x > mainPanel.getImageWidth())
                    x = mainPanel.getImageWidth();
                if (y > mainPanel.getImageHeight())
                    y = mainPanel.getImageHeight();
                Currentline.endPoint = new Point2D.Double(x, y);
                mainPanel.addMeasuringLine(Currentline);
                mainPanel.repaint();
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
        }
    }

}

3. 最后显示的地方:

public class ImagePane extends JLayeredPane implements Scrollable,
        Zoomable {

private List<MeasuringLine> measuringLine = new ArrayList<MeasuringLine>();

    public ImagePane (float maxZoomScale, float minZoomScale) {
        this(maxZoomScale, minZoomScale, true);
    }

protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null) {
            g.drawImage(image, 0, 0, (int) (image.getWidth() * scale),
                    (int) (image.getHeight() * scale), this);
            Color oldColor = g.getColor();
            // 画矩形边框
            g.setColor(Color.BLACK);
            g.drawRect(0, 0, (int) (image.getWidth() * scale),
                    (int) (image.getHeight() * scale));
            g.setColor(oldColor);
            // 这个地方就是添加画箭头的地方
            Graphics2D g2 = (Graphics2D) g.create();
            Color beforeColor = g.getColor();
            g.setColor(Color.red);
                for (int i = 0; i < measuringLine.size(); i++) {
                    MeasuringLine line1 = measuringLine.get(i);
                    line1.MeasuringDistance();
                    // 绘制线的“双向”箭头
                    double startx = line1.getStartPoint().getX() * scale;
                    double starty = line1.getStartPoint().getY() * scale;
                    double endX = line1.getEndPoint().getX() * scale;
                    double endY = line1.getEndPoint().getY() * scale;
                    double Middlex = line1.getMiddlePoint().getX() * scale;
                    double Middley = line1.getMiddlePoint().getY() * scale;
                    line1.paint(g2, startx, starty, endX, endY);
                    g.drawString(line1.getStrdistance(), (int) Middlex,
                            (int) Middley);
                }
                g.setColor(beforeColor);
            }
            
            this.setPreferredSize(new Dimension(
                    (int) (image.getWidth() * scale),
                    (int) (image.getHeight() * scale)));
            this.updateUI();
        }
    }
这样就可以实现页面的测距功能。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值