作为我正在编写的程序的一部分,我希望将图像打印为SVG格式。我需要它是SVG格式,以便我可以稍后使用Adobe Illustrator对其进行修改。虽然我可以直接在print方法中绘制一个矩形并成功导出为SVG格式。
当我在getTagCloud
方法中绘制相同的矩形时,结果(当打印到SVG时)是一个由大量小矩形组成的矩形。我不知道为什么会出现这种情况,但希望对于读这篇文章的人来说,答案显而易见!
最终,我需要打印的不仅仅是一个矩形,但Illustrator中导出的“Group”是如此之大(包含所有这些不同大小的小矩形),我无法找到我拥有的其他对象绘制(因为一切,无论我最初使用什么颜色,都是黑色渲染)。任何帮助将不胜感激。 以下是相关代码。我没有包含import语句,因为编译代码没有任何问题。
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();
}
答案 0 :(得分:1)
如果没有关于Java BufferedImage
,Graphics
,PrinterJob
以及其他相关类实现的知识,我无能为力。 (你可以为这个问题开始一个赏金,以吸引那些对java awt图形内容有更多内在知识的人的注意力。)
正如您显然必须注意到使用BufferedImage
(或不使用它)是SVG输出的不同之处。在可用的版本中,您直接在Graphic
上下文中绘制矩形作为print()
方法参数提供给您,我相信它是如何设计为由Printable
接口和打印的作者使用的框架。
在第二种方法(无法正常工作)中,首先将矩形绘制到新的BufferedImage
对象上,然后在提供的Graphic
上下文中绘制此图像。所以你做的事情要比直接在上下文中绘制更简单。开发人员众所周知的事实或直觉是,你使用某种API的方式越简单,你做作意外的机会就越大:(。
我的注意事项如下:BufferedImage
是(因为你可以从它的Javadocs中推断出来)只是一个光栅图像,即。像素网格。这就是为什么svg文件填充了许多小矩形(试图模仿像素)。 Graphics
方法提供的draw()
对象可能更抽象,对形状而不是像素进行操作,这更适合写入SVG等矢量图形格式。但这只是一种幻想。
问题是,你真的需要使用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
是您自己的自定义类的对象,它只存储有关用户编辑的图像的数据)