- - PR -
Swingのペイント
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-07-28 00:17
こんばんわ。
また質問させて頂きます。。 1画像を読み込み 2表示させ 3その画像に描画し 4その画像を保存する という物を作っているのですが、 12は出来るのですが、 3が出来ないのです。 ネットで調べて描画機能は発見し取り入れたので、 出来るとは思うのですが、出来ません。 描画は画像をロードしていない状態では出来ますが、 画像をロードした後に描画できないという状態です。 一応コードを載せます。 コード: import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.*; import java.awt.image.*; import java.util.*; import java.util.List; import javax.imageio.stream.*; import java.awt.image.BufferedImage ; import java.awt.Graphics ; import java.awt.Dimension ; import java.awt.Color ; import java.awt.geom.* ; import java.awt.Graphics2D ; import java.awt.BasicStroke ; public class POSE{ public static void main(String[] args){ MyFrame mf = new MyFrame(); mf.setTitle("PaintOpenSaveEdit"); mf.setSize(600, 500); mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mf.show(); } } class MyFrame extends JFrame { private JMenuBar menuBar; private JFileChooser fileChooser; private MyPanel panel; private BufferedImage[] images; private static Set readerSuffixes = getReaderSuffixes(); private static Set writerFormats = getWriterFormats(); Point2D.Double p1 = new Point2D.Double(); // 始点 Point2D.Double p2 = new Point2D.Double(); // 終点 Line2D.Double line = new Line2D.Double(); // 直線 BufferedImage image = null; // イメージ Graphics2D imageGraphics; // イメージのGraphics final static Color bc = Color.white; // 背景色 public MyFrame(){ panel = new MyPanel(); getContentPane().setLayout(new BorderLayout()); getContentPane().add(panel, "Center"); addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { p1.setLocation(p2); p2.setLocation((double)e.getX(), (double)e.getY()); repaint(); } }); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { p1.setLocation((double)e.getX(), (double)e.getY()); p2.setLocation(p1); } }); setBackground(bc); JMenu fileMenu = new JMenu("File"); JMenuItem openItem = new JMenuItem("Open"); openItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { openFile(); } }); fileMenu.add(openItem); JMenu saveMenu = new JMenu("Save"); fileMenu.add(saveMenu); Iterator iter = writerFormats.iterator(); while (iter.hasNext()) { final String formatName = (String)iter.next(); JMenuItem formatItem = new JMenuItem(formatName); saveMenu.add(formatItem); formatItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { saveFile(formatName); } }); } JMenuItem exitItem = new JMenuItem("Exit"); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); fileMenu.add(exitItem); JMenu editMenu = new JMenu("Edit"); JMenuItem editItem = new JMenuItem("Clear"); editItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { repaint(); } }); JMenuBar menuBar = new JMenuBar(); menuBar.add(fileMenu); setJMenuBar(menuBar); } public void openFile() { JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); chooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { if (f.isDirectory()) return true; String name = f.getName(); int p = name.lastIndexOf('.'); if (p == -1) return false; String suffix = name.substring(p + 1).toLowerCase(); return readerSuffixes.contains(suffix); } public String getDescription() { return "Image files"; } }); int r = chooser.showOpenDialog(this); if (r != JFileChooser.APPROVE_OPTION) return; File f = chooser.getSelectedFile(); Box box = Box.createVerticalBox(); try { String name = f.getName(); String suffix = name.substring(name.lastIndexOf('.') + 1); Iterator iter = ImageIO.getImageReadersByFormatName(suffix); ImageReader reader = (ImageReader)iter.next(); ImageInputStream imageIn = ImageIO.createImageInputStream(f); reader.setInput(imageIn); int count = reader.getNumImages(true); images = new BufferedImage[count]; for (int i = 0; i < count; i++) { images[i] = reader.read(i); box.add(new JLabel(new ImageIcon(images[i]))); } } catch (IOException exception) { JOptionPane.showMessageDialog(this, exception); } setContentPane(new JScrollPane(box)); validate(); } public void saveFile(final String formatName) { if (images == null) return; Iterator iter = ImageIO.getImageWritersByFormatName( formatName); ImageWriter writer = (ImageWriter)iter.next(); final List writerSuffixes = Arrays.asList( writer.getOriginatingProvider().getFileSuffixes()); JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); chooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { if (f.isDirectory()) return true; String name = f.getName(); int p = name.lastIndexOf('.'); if (p == -1) return false; String suffix = name.substring(p + 1).toLowerCase(); return writerSuffixes.contains(suffix); } public String getDescription() { return formatName + " files"; } }); int r = chooser.showSaveDialog(this); if (r != JFileChooser.APPROVE_OPTION) return; File f = chooser.getSelectedFile(); try { ImageOutputStream imageOut = ImageIO.createImageOutputStream(f); writer.setOutput(imageOut); writer.write(new IIOImage(images[0], null, null)); for (int i = 1; i < images.length; i++) { IIOImage iioImage = new IIOImage(images[i], null, null); if (writer.canInsertImage(i)) writer.writeInsert(i, iioImage, null); } } catch (IOException exception) { JOptionPane.showMessageDialog(this, exception); } } public static Set getReaderSuffixes() { TreeSet readerSuffixes = new TreeSet(); String[] informalNames = ImageIO.getReaderFormatNames(); for (int i = 0; i < informalNames.length; i++) { Iterator iter = ImageIO.getImageReadersByFormatName( informalNames[i]); while (iter.hasNext()) { ImageReader reader = (ImageReader)iter.next(); String[] s = reader.getOriginatingProvider() .getFileSuffixes(); readerSuffixes.addAll(Arrays.asList(s)); } } return readerSuffixes; } public static Set getWriterFormats() { TreeSet writerFormats = new TreeSet(); TreeSet formatNames = new TreeSet(Arrays.asList( ImageIO.getWriterFormatNames())); while (formatNames.size() > 0) { String name = (String)formatNames.iterator().next(); Iterator iter = ImageIO.getImageWritersByFormatName( name); ImageWriter writer = (ImageWriter)iter.next(); String[] names = writer.getOriginatingProvider() .getFormatNames(); writerFormats.add(names[0]); formatNames.removeAll(Arrays.asList(names)); } return writerFormats; } public void paintComponent(Graphics g) { if(image==null) { Dimension d = getSize(); int w = d.width; int h = d.height; image = (BufferedImage)createImage(w,h); imageGraphics = (Graphics2D)image.createGraphics(); imageGraphics.setBackground(bc); imageGraphics.clearRect(0, 0, w, h); imageGraphics.setStroke(new BasicStroke(3.0F)); } if(!p1.equals(p2)) { line.setLine(p1,p2); imageGraphics.draw(line); ((Graphics2D)g).drawImage(image, 0, 0, this); p1.setLocation(p2); } g.drawImage(image, 0, 0, this); } } [ メッセージ編集済み 編集者: KDS 編集日時 2005-07-28 00:17 ] | ||||||||||||
|
投稿日時: 2005-07-28 17:10
MyPanelがないので、ぱっと見たところなんですが、
1.paintComponentメソッドで画像が後で描画されて線が塗りつぶされている? 2.というかpaintComponentメソッドが全く呼ばれていない? 3.ロードしたあとに、ContentPaneを入れ替えている? などなどでしょうか。 以下、MyPanelをJPanelで代用して変更してみました。 public MyFrame(){ panel = new JPanel(new BorderLayout()) { public void paintComponent(Graphics g) { if(image!=null) { Dimension d = getSize(); int w = d.width; int h = d.height; ((Graphics2D)g).clearRect(0, 0, w, h); ((Graphics2D)g).drawImage(image, 0, 0, this); } line.setLine(p1,p2); ((Graphics2D)g).draw(line); } }; //getContentPane().setLayout(new BorderLayout()); getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER); panel.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { //p1.setLocation(p2); p2.setLocation((double)e.getX(), (double)e.getY()); repaint(); } }); panel.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { p1.setLocation((double)e.getX(), (double)e.getY()); //p2.setLocation(p1); } }); panel.setBackground(bc); 以下省略 以下はopenFileメソッドで File f = chooser.getSelectedFile(); //Box box = Box.createVerticalBox(); try { image = ImageIO.read(f.toURL()); panel.setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); }catch(IOException exception) { JOptionPane.showMessageDialog(this, exception); } //setContentPane(new JScrollPane(box)); panel.revalidate(); | ||||||||||||
|
投稿日時: 2005-07-28 21:00
Araiさん
返信ありがとうございます。 言われたとおりプログラムを変更し、 実行してみました。 そうしたら、画像のロード前もロード後も描画出来るようになりました。 ありがとうございます。 しかし、描画の部分が直線になってしまいました。。。 元のファイルはフリーラインなのですが。。。 もう少し考えて見ます。 それでも分からなかったらまた質問させて頂きます。 | ||||||||||||
|
投稿日時: 2005-07-29 12:40
まぁ、せっかくだから変更したコード投稿しときます。元々KDSさんが参考にしたコードと、
KDSさんがここに投稿したコードなどなどと比較てみてください。 private final JPanel panel; private Point2D.Double p1 = new Point2D.Double(); // 始点 private Point2D.Double p2 = new Point2D.Double(); // 終点 private Line2D.Double line = new Line2D.Double(); // 直線 private BufferedImage image = null; // イメージ //Graphics2D imageGraphics; // イメージのGraphics private boolean flag = false; public MyFrame(){ panel = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); ((Graphics2D)g).drawImage(image, 0, 0, this); } }; this.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER); panel.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { p1.setLocation(p2); p2.setLocation((double)e.getX(), (double)e.getY()); if(image==null) { Dimension d = panel.getSize(); int w = d.width; int h = d.height; image = (BufferedImage)panel.createImage(w,h); } Graphics2D imageGraphics = (Graphics2D)image.createGraphics(); imageGraphics.setStroke(new BasicStroke(3.0F)); imageGraphics.setPaint(Color.black); if(flag) { imageGraphics.drawImage(image, 0, 0, null); flag = false; } if(!p1.equals(p2)) { line.setLine(p1,p2); imageGraphics.draw(line); p1.setLocation(p2); } imageGraphics.dispose(); repaint(); } }); panel.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { p1.setLocation((double)e.getX(), (double)e.getY()); p2.setLocation(p1); } }); 以下省略 openFile()メソッド内の一部 try{ image = ImageIO.read(f.toURL()); getContentPane().setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); flag = true; | ||||||||||||
|
投稿日時: 2005-07-29 18:25
Araiさん
ありがとうございます。 Araiさんのコードでいろいろ検証してみた結果、 起動に時間がかかりNullPointerExceptionが発生しますが。。 ちゃんとフリーラインで描く事が出来ました^^ あとは画像を保存するだけなので、 AraiさんのopenFileと私のsaveFileを比較検証しながら、 またプログラムをいじってみたいと思います。 ほんとうにありがとうございました。 [ メッセージ編集済み 編集者: KDS 編集日時 2005-07-29 18:36 ] | ||||||||||||
|
投稿日時: 2005-07-30 21:07
また質問させて頂きます。。
Araiさんのコードを基に頑張ってみまして、 ロード(open)が出来るようになりましたが、 セーブ(save)が上手く行きません。 上手く行かないというのは、 jpgとpngファイルで保存できるように設定しているのですが、 jpg及びpngファイルを生成しても、 画像が表示できないのです。 プレビューを利用できませんと言われてしまいます。 多分少しの差で出来るようになると思うのですが。。。 あとこれも少しの差だとは思うのですが、 Fileメニューは使う事が出来るのですが、 その横のEditメニューが使う事が出来ません。 これも少しの差だと思うのですが。。 分かる方いらっしゃいましたら、 よろしくお願い致します。。 またコードを載せます。。。
[ メッセージ編集済み 編集者: KDS 編集日時 2005-07-30 22:31 ] [ メッセージ編集済み 編集者: KDS 編集日時 2005-08-01 19:54 ] | ||||||||||||
|
投稿日時: 2005-07-30 21:19
unibon です。こんにちわ。
ソースコードを載せられるのは、具体的になり賢明だとは思いますが、なんだかデバッグしてください、みたいな流れになっているのが気にかかります。○○ができない、というだけではなく、どの点が問題になっていてどう試行されたのかを書いていただけると傍観者としては分かりやすくて嬉しいのですが。たしかに、ソースコードがあるので、それが全てを物語っているわけですから、ソースコードを見れば分かることなのですが、しかし、コードを全部見ないといけないのも大変ですし。 あと、些細なことですがコードはBBコードの [CODE] タグで囲っていただけると、字下げが残るので見やすくなって助かります。 | ||||||||||||
|
投稿日時: 2005-07-30 22:40
unibonさん
レスありがとうございます。 とりあえず
どの点が問題になっているのかというのは
この部分と public void saveFile(final String formatName) のメソッドだと思います。 Araiさんのコードを基に プログラムをいじったのですが 。。。という感じですね。。。 Editメニューの部分は
Editはなぜ出来ないかわかりません。 他の部分が悪いのでしょうか?? [ メッセージ編集済み 編集者: KDS 編集日時 2005-08-01 19:54 ] |