2

作为我正在编写的程序的一部分,我希望将图像打印为 SVG 格式。我需要它是 SVG 格式,以便以后可以使用 Adob​​e Illustrator 对其进行修改。就目前而言,虽然我可以直接在 print 方法中绘制一个矩形并将其成功导出为 SVG 格式。

当我在我的getTagCloud方法中绘制相同的矩形时,结果(当打印到 SVG 时)是一个由大量小矩形组成的矩形。我不知道为什么会这样,尽管希望答案对阅读本文的人来说是显而易见的!

最终,我需要打印的不仅仅是一个矩形,但 Illustrator 中导出的“组”太大(包含所有这些不同大小的小矩形),我无法找到我绘制的其他对象(如一切,无论我最初使用什么颜色,都呈现为黑色)。任何帮助将不胜感激。下面是相关代码。我没有包含导入语句,因为我在编译代码时没有任何问题。

public class TagCloud {

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI(); 
        }
    });
}

public static void createAndShowGUI() {
    System.out.println("Created GUI on EDT? "+
    SwingUtilities.isEventDispatchThread());
    JFrame f = new JFrame("Tag Cloud Generator");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MyPanel myPanel = new MyPanel();

    Toolkit tk = f.getToolkit();       
    Dimension wndSize = tk.getScreenSize();  


    f.setBounds(0, 0,   
                      wndSize.width, wndSize.height); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {System.exit(0);}
        });

    f.add("Center",myPanel);
    f.pack();
    f.setVisible(true);
    myPanel.printTagCloud();

}


}

class MyPanel extends JPanel implements Printable{

private int squareX = 50;
private int squareY = 50;
private int squareW = 20;
private int squareH = 20;
private int x_offset = 30;
private int y_offset = 30;
private BufferedImage img = null;
private int defaultFontSize = 16;




public int print(Graphics g, PageFormat pf, int page) throws
                                                    PrinterException {

    if (page > 0) { /* We have only one page, and 'page' is zero-based */
        return NO_SUCH_PAGE;
    }

    Graphics2D g2d = (Graphics2D)g;
    g2d.translate(pf.getImageableX(), pf.getImageableY());

    if (img == null){
        getTagCloudImage();

    } 
    g.setColor(Color.red);
    g.fillRect(0, 0, 250, 400);
    //g.drawImage(img, 0, 0, null);
    g.dispose();

    return PAGE_EXISTS;
}

public void printTagCloud(){

    PrinterJob job = PrinterJob.getPrinterJob();
    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
    PageFormat pf = job.pageDialog(aset);
    job.setPrintable(this);
    boolean ok = job.printDialog(aset);
    if (ok) {
        try {
             job.print(aset);
        } catch (PrinterException ex) {

        }
    }
}

public MyPanel() {
    setBorder(BorderFactory.createLineBorder(Color.black));


    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            moveSquare(e.getX(),e.getY());
        }
    });

    addMouseMotionListener(new MouseAdapter() {
        public void mouseDragged(MouseEvent e) {
            moveSquare(e.getX(),e.getY());
        }
    });
}

private void moveSquare(int x, int y) {

    int OFFSET = 1;
    if ((squareX!=x) || (squareY!=y)) {
        repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
        squareX=x;
        squareY=y;
        repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
    } 
}

public Dimension getPreferredSize() {
    return new Dimension(1000,800);
}

public void paintComponent(Graphics g) {
    super.paintComponent(g); 
if (img == null){
    getTagCloudImage();
    } 
else{

    g.drawImage(img, x_offset, y_offset, null);
}

}


public void getTagCloudImage(){

img = new BufferedImage(250, 250, BufferedImage.TYPE_INT_RGB); 


Graphics g = img.getGraphics();
Graphics2D g2 = (Graphics2D)g;

Rectangle r = new Rectangle (0,0,250,250);
g2.draw(r);
g2.setColor(Color.black);
g2.fill(r);
g2.dispose();
}
4

1 回答 1

1

如果不了解 Java BufferedImage、和其他相关类的实现Graphics,我将无能为力。PrinterJob(您可能会为这个问题开始赏金,以引起对 java awt 图形内容有更多内在知识的人的注意)。

正如您显然必须注意到的那样,使用BufferedImage(或不使用)是 SVG 输出的不同之处。在有效的版本中,您可以直接在Graphic作为方法参数提供给您的上下文上绘制矩形print(),我相信这就是它被设计为供Printable界面和打印框架的作者使用的方式。

在第二种方法(不正确)中,您首先将矩形绘制到新 BufferedImage对象上,然后在提供的Graphic上下文中绘制此图像。所以你做的事情远没有直接在上下文中绘制那么简单。开发人员有一个众所周知的事实或直觉,即您使用某些 API 的方式越不直接,您做其作者意想不到的事情的机会就越大:(。

我的假设如下:是(正如你可以从它的JavadocsBufferedImage中推断出来的)只是一个光栅图像,即。像素网格。这就是为什么 svg 文件中填充了许多小矩形(试图模仿像素)。方法提供的对象可能更抽象,对形状而不是像素进行操作,这更适合写入SVG等矢量图形格式。但这只是假设。Graphicsdraw()

问题是,你真的需要使用BufferedImage吗?如果我理解正确,您希望用户能够在屏幕上编辑矩形,并在准备好时将其导出为 SVG。你不能只记住用户编辑的矩形的左上角和尺寸,然后使用这些数据直接在Graphics提供的对象上重新创建这个矩形print(),比如:

public int print(Graphics g, PageFormat pf, int page)
  throws PrinterException {
...
  g.fillRect(userRect.x,userRect.y,userRect.width,userRect.height);
...
}

?

userRect是您自己的自定义类的对象,它只存储有关用户编辑的图像的数据)

于 2013-01-27T22:05:03.573 回答