2

私が書いているプログラムの一部として、画像を SVG 形式で印刷したいと考えています。後で Adob​​e Illustrator を使用して変更できるように、SVG 形式にする必要があります。現状では、印刷メソッドで直接長方形を描画し、それを 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

BufferedImageJava 、GraphicsPrinterJobおよびその他の関連クラスの実装に関する知識がなければ、私はあまり役に立ちません。(Java awt グラフィックに関するより内在的な知識を持っている人々の注意を引くために、この質問に対して報奨金を開始することができます)。

BufferedImageSVG を使用する(または使用しない) ことで、SVG 出力に違いが生じることは明らかです。機能するバージョンでは、メソッドの引数Graphicとして提供されたコンテキストに直接長方形を描画します。これは、インターフェイスと印刷フレームワークの作成者が使用するように設計された方法だと思います。print()Printable

2 番目のアプローチ (これは正しく機能しません) では、最初に新しい BufferedImageオブジェクトに四角形を描画し、次に提供されたGraphicコンテキストでこの画像を描画します。したがって、コンテキストに直接描画するよりもはるかに単純ではありません。開発者の間では、API の使用方法が単純ではないほど、その作成者が予期しないことを行う可能性が高くなるという、よく知られている真実または直感があります :(.

私の仮説は次のとおりです。(JavadocsからBufferedImage推測できるように)単なるラスター画像です。ピクセルのグリッド。そのため、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 に答える