代码之家  ›  专栏  ›  技术社区  ›  Tim Frey

Java2D:用线剪裁图形对象

  •  0
  • Tim Frey  · 技术社区  · 16 年前

    有没有一种方法可以使用图形对象的“setClip()”方法来使用略带线条的形状进行剪裁?现在我正在尝试使用多边形,但是我在模拟线条的“宽度”时遇到了问题。我基本上画了这条线,当我到达终点时,我重新画了它,但是这次从y坐标减去了线宽:

    Polygon poly = new Polygon();
    
    for(int i = 0; i < points.length; i++)
      poly.addPoint(points.[i].x, points.[i].y);
    
    // Retrace line to add 'width'
    for(int i = points.length - 1; i >=0; i--)
      poly.addPoint(points[i].x, points[i].y - lineHeight);
    

    它几乎可以工作,但线条的宽度因坡度而异。

    我不能使用BrushStroke和drawLine()方法,因为一旦线条通过某个任意的参考线,它就会改变颜色。是否有一些我忽略的形状实现,或者一个我可以创建的简单的实现,让我更容易做到这一点?

    3 回复  |  直到 16 年前
        1
  •  1
  •   Michael Myers KitsuneYMG    16 年前

    如果有更好的方法,我从来没有遇到过。我能想到的最好的办法就是用三角法使线宽更一致。

        2
  •  1
  •   Tim Frey    16 年前

    好吧,我没有使用setClip()方法就想出了一个很好的解决方案。它包括将背景绘制到中间Graphics2D对象,使用setComposite()指定如何遮罩像素,然后在顶部使用drawLine()绘制线条。一旦我有了这条线,我就通过drawImage把它画回到我原来的图形对象上。下面是一个例子:

    BufferedImage mask = g2d.getDeviceConfiguration().createCompatibleImage(width, height, BufferedImage.TRANSLUCENT);
    Graphics2D maskGraphics = (Graphics2D) mask.getGraphics();
    maskGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
    maskGraphics.setStroke(new BasicStroke(lineWidth));
    maskGraphics.setPaint(Color.BLACK);
    
    // Draw line onto mask surface first.
    Point prev = line.get(0);
    for(int i = 1; i < line.size(); i++)
    {
        Point current = line.get(i);
        maskGraphics.drawLine(prev.x, prev.y, current.x, current.y);
            prev = current;
    }
    
    // AlphaComposite.SrcIn:    "If pixels in the source and the destination overlap, only the source pixels
    //                          in the overlapping area are rendered."
    maskGraphics.setComposite(AlphaComposite.SrcIn);
    
    maskGraphics.setPaint(top);
    maskGraphics.fillRect(0, 0, width, referenceY);
    
    maskGraphics.setPaint(bottom);
    maskGraphics.fillRect(0, referenceY, width, height);
    
    g2d.drawImage(mask, null, 0, 0);
    maskGraphics.dispose();
    
        3
  •  0
  •   tofarr    14 年前

    也许你可以用Stroke.createClippedShape来做这个?(可能需要使用一个区域将笔划形状从原始形状中加/减到原始形状,具体取决于您正试图执行的操作。