1

我想在 Java 中对图像应用笔画(轮廓)。在阅读了这个这个之后,看起来 Java2D API 只将笔划应用于形状?当然,我可以进行位图填充,然后对该形状应用笔触,但我想知道是否可以直接在给定的位图上应用它。

更新:我设法应用了一个描边位,它勾勒出整个图像。我的图像具有 PNG 透明度。如何仅在图像的可见像素周围应用描边?

 public static void main(String[] args) {
    try {
        // TODO code application logic here
        URL u = GraphicsDemo.class.getResource("Capture222.png");
        BufferedImage img = ImageIO.read(new File(u.getPath()));
        System.out.print("loaded");
        Graphics2D g = img.createGraphics();
        Rectangle2D tr = new Rectangle2D.Double(0, 0,
                img.getWidth(), img.getHeight());
        // Create the TexturePaint.
        TexturePaint tp = new TexturePaint(img, tr);
        g.setStroke(new BasicStroke(20));
        g.setPaint(Color.ORANGE);
        //   g.fill(tr);
        g.draw(tr);


        ImageIO.write(img, "PNG", new File("myeditedimage.png"));
        g.dispose();
    } catch (IOException ex) {
        Logger.getLogger(GraphicsDemo.class.getName()).log(Level.SEVERE, null, ex);
    }
 } 

更新 1:我不确定使用 Java 图形 API 是否可以尝试做。再一次。我需要根据可见像素轮廓而不是围绕它的边界框来勾勒图像。这就是我想要实现的目标: 在此处输入图像描述

4

5 回答 5

2

是的,Java2D API 仅将笔划应用于形状。你可以做两件事:

从位图图像的透明度信息中创建一个 Shape ,这样您就可以只描边不透明的部分。这在任何语言中都是困难的,因为这意味着将位图信息转换为基于矢量的信息

检查这个:图像/图形变成形状

这:平滑锯齿状路径

但基本上我会尽量避免转换问题,并以仅位图的方式解决它 - 例如,对在给定像素距离处可以找到透明像素的那些像素(使用“描边颜色”)着色( “笔画宽度”)。

于 2012-08-22T15:01:26.180 回答
0
  • 首先,Graphics2D通过调用来告诉你希望如何绘制轮廓setStroke()。此方法接受任何实现java.awt.Stroke interface. 2D API 带有一个类,java.awt.BasicStroke,它实现了常见的描边选项。
  • 用于setPaint()告诉Graphics2D应该如何绘制轮廓本身。轮廓,就像形状的内部一样,可以使用颜色、渐变、纹理或任何其他实现 Paint 接口的东西来绘制。
  • draw()使用 Graphics2D 的方法绘制形状的轮廓。Graphics2D 使用步骤 1 中的 Stroke 来确定轮廓的外观。步骤 2 中的 Paint 用于实际渲染轮廓。

Graphics2D使用 Stroke 来确定特定形状的轮廓是什么样的。当你询问Graphics2D一个draw()形状时,它会询问它的 Stroke 形状的轮廓应该是什么样子。有趣的是,Stroke 将描边的轮廓返回为另一种形状:

public abstract Shape createStrokedShape(Shape p)

此方法返回一个表示所提供形状的描边轮廓的 Shape。这是 Stroke 中唯一的方法。通常,您不会自己调用它,aGraphics2D会在您draw()创建 shape 时代表您调用它。

调用draw()aGraphics2D等价于以下代码:

public void longwindedDraw(Graphics2D g2, Shape s) 
{
    Stroke stroke = g2.getStroke();
    Shape strokedOutline = stroke.createStrokedShape(s);
    g2.fill(strokedOutline);
}
于 2012-08-21T07:27:07.380 回答
0

试试这个 :

final static BasicStroke dash_stroke =new BasicStroke(1.0f,
                        BasicStroke.CAP_BUTT,
                        BasicStroke.JOIN_MITER,
                        10.0f, dash1, 0.0f);

然后设置 Stroke :

g2.getStroke()
于 2012-08-21T08:26:30.823 回答
-1

要获取在位图上绘制的 Graphics2D 对象,您应该使用 BufferedImage。

BufferedImage img = ImageIO.read(new File("myimage.png"));
Graphics2D g = img.createGraphics();

// Paint on it like you want here...


g.dispose();
ImageIO.write(img, "PNG", new File("myeditedimage.png"));
于 2012-08-21T07:21:06.623 回答
-1

像这样?如果没有,请附上显示所需结果的图像。

描边图像

import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class StrokedImage {

    public BufferedImage getStrokedImage(
            BufferedImage bi, Shape shape, int strokeWidth) {
        int w = bi.getWidth();
        int h = bi.getHeight();
        BufferedImage bib = new BufferedImage(w,h,bi.getType());
        Graphics2D g = bib.createGraphics();

        BasicStroke bs = new BasicStroke(strokeWidth);
        g.setStroke(bs);
        Rectangle rect = new Rectangle(0,0,w,h); 
        TexturePaint tp = new TexturePaint(bi, rect); 
        g.setPaint(tp);
        g.draw(shape);

        g.dispose();
        return bib;
    }

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://pscode.org/media/stromlo1.jpg");
        final BufferedImage bi = ImageIO.read(url);
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                StrokedImage si = new StrokedImage();

                int strokeWidth = 12;
                int pad = 50;
                Shape shape = new Rectangle(
                        pad,pad,
                        bi.getWidth()-(2*pad),bi.getHeight()-(2*pad)); 
                Image i = si.getStrokedImage(bi, shape, strokeWidth);

                JPanel p = new JPanel(new GridLayout(1,0,5,5));
                p.add(new JLabel(new ImageIcon(i)));
                p.add(new JLabel(new ImageIcon(bi)));
                JOptionPane.showMessageDialog(null, p);
            }
        });
    }
}

发布问题编辑 - 更新

看看这个答案Shape它在绘制图像之前应用剪辑。然后它清除剪辑并将其Shape自身绘制为边框。

于 2012-08-21T23:45:41.473 回答