diff --git a/.gitignore b/.gitignore index ab91aba..8d6a41a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /importPicture/classes/ /importPicture/deploy/ +/importPicture/AdjustTime/nbproject/private/ \ No newline at end of file diff --git a/importPicture/src/AdjustTime.ini b/importPicture/src/AdjustTime.ini new file mode 100644 index 0000000..d9e599a --- /dev/null +++ b/importPicture/src/AdjustTime.ini @@ -0,0 +1 @@ +javaw -cp .;AdjustTime2.jar;commons-imaging-1.0-SNAPSHOT.jar osm.jp.gpx.matchtime.gui.AdjustTime \ No newline at end of file diff --git a/importPicture/src/osm/jp/gpx/Config.java b/importPicture/src/osm/jp/gpx/Config.java new file mode 100644 index 0000000..9f843a1 --- /dev/null +++ b/importPicture/src/osm/jp/gpx/Config.java @@ -0,0 +1,27 @@ +package osm.jp.gpx; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * シンプルなサンプルログフォーマッタ + */ +public class Config { + static Properties configuration = null; + + public static Properties getProperties() throws IOException { + if (configuration == null) { + configuration = new Properties(); + File f = new File("AdjustTime.ini"); + if (f.isFile()) { + InputStream iniStream = new FileInputStream(f); + configuration.load(iniStream); + } + } + return configuration; + } + +} \ No newline at end of file diff --git a/importPicture/src/osm/jp/gpx/ImportPicture.java b/importPicture/src/osm/jp/gpx/ImportPicture.java index dae0c3b..29d4c4b 100644 --- a/importPicture/src/osm/jp/gpx/ImportPicture.java +++ b/importPicture/src/osm/jp/gpx/ImportPicture.java @@ -10,7 +10,6 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; -import java.util.Properties; import java.util.Set; import java.util.TimeZone; import java.util.TreeMap; @@ -79,6 +78,8 @@ } } } + + /** メイン * 画像ファイルをGPXファイルに取り込みます。 @@ -196,15 +197,11 @@ 9 */ - - Properties configuration = new Properties(); DocumentBuilderFactory factory; DocumentBuilder builder; Node gpx; try { - InputStream iniStream = new FileInputStream(new File("AdjustTime.ini")); - configuration.load(iniStream); outDir = new File(outDir, imgDir.getName()); diff --git a/importPicture/src/osm/jp/gpx/matchtime/gui/AdjustTime.java b/importPicture/src/osm/jp/gpx/matchtime/gui/AdjustTime.java index bea0e3b..a40f8a8 100644 --- a/importPicture/src/osm/jp/gpx/matchtime/gui/AdjustTime.java +++ b/importPicture/src/osm/jp/gpx/matchtime/gui/AdjustTime.java @@ -2,9 +2,25 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; +import java.io.IOException; import java.util.Date; +import java.util.Properties; + import javax.swing.*; -import osm.jp.gpx.ImportPicture; + +import osm.jp.gpx.*; +import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.Imaging; +import org.apache.commons.imaging.common.ImageMetadata; +import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata; +import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; +import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants; +import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory; +import org.apache.commons.imaging.formats.tiff.write.TiffOutputField; +import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet; + + /** * 本プログラムのメインクラス @@ -26,14 +42,15 @@ JPanel argsPanel; // パラメータ設定パネル (上部) JScrollPane imageSPane; // スクロールパネル JLabel imageLabel; // 基準時刻画像表示 + JCheckBox exifBase; // EXIF日時を基準にする/ !(ファイル更新日時を基準にする) JTextArea textArea; // 実行結果表示領域 //ImagePreview imagePane; // 基準時刻画像表示 - ParameterPanelFolder arg1Panel_1; - ParameterPanelImageFile arg1Panel_2; - ParameterPanel arg1Panel_3; - JRadioButton exifON; // EXIF 書き出しモード - ParameterPanelFolder arg1Panel_4; // EXIF 書き出しフォルダ - ParameterPanelFolder arg1Panel_5; // GPXファイル・フォルダ + ParameterPanelFolder arg1_srcFolder; + ParameterPanelImageFile arg2_baseTimeImg; + ParameterPanel arg3_basetiome; + JCheckBox exifON; // EXIF 書き出しモード / !(EXIFの書き換えはしない) + ParameterPanelFolder arg5_outputFolder; // EXIF 書き出しフォルダ + ParameterPanelFolder arg4_gpxFolder; // GPXファイル・フォルダ JPanel buttonPanel; // ボタンパネル (下部) JButton openButton; // [Fit]ボタン @@ -88,13 +105,16 @@ else if (object == zoomOutButton) { zoomout_Action(event); } - else if (object == arg1Panel_2.argField) { + else if (object == arg2_baseTimeImg.argField) { imageView_Action(event); } - else if (object == arg1Panel_2.openButton) { + else if (object == arg2_baseTimeImg.openButton) { selectImage_Action(event); imageView_Action(event); } + else if (object == exifON) { + exifON_Action(event); + } else if (object == doButton) { doButton_Action(event); } @@ -106,11 +126,14 @@ } } } + + Properties config; /** * データベース内のテーブルを一覧で表示するFrame + * @throws IOException */ - public AdjustTime() + public AdjustTime() throws IOException { // INIT_CONTROLS Container container = getContentPane(); @@ -118,6 +141,8 @@ setSize(getInsets().left + getInsets().right + 960,getInsets().top + getInsets().bottom + 480); setTitle(AdjustTime.PROGRAM_NAME +" v"+ AdjustTime.PROGRAM_VARSION); + config = Config.getProperties(); + //--------------------------------------------------------------------- cardPanel = new JPanel(); cardPanel.setLayout(new CardLayout()); @@ -146,8 +171,8 @@ argsPanel = new JPanel(); argsPanel.setLayout(new BoxLayout(argsPanel, BoxLayout.Y_AXIS)); - arg1Panel_1 = new ParameterPanelFolder("対象フォルダ: ", (new File(".")).getAbsolutePath()); - argsPanel.add(arg1Panel_1); + arg1_srcFolder = new ParameterPanelFolder("対象フォルダ: ", (new File(".")).getAbsolutePath()); + argsPanel.add(arg1_srcFolder); cards[cardNo].add(argsPanel, BorderLayout.CENTER); //--------------------------------------------------------------------- @@ -160,8 +185,12 @@ argsPanel = new JPanel(); argsPanel.setLayout(new BoxLayout(argsPanel, BoxLayout.Y_AXIS)); - arg1Panel_2 = new ParameterPanelImageFile("基準時刻画像: ", "", arg1Panel_1); - argsPanel.add(arg1Panel_2); + arg2_baseTimeImg = new ParameterPanelImageFile("基準時刻画像: ", "", arg1_srcFolder); + argsPanel.add(arg2_baseTimeImg); + + exifBase = new JCheckBox("EXIFの日時を基準にする", false); + exifBase.setEnabled(false); + argsPanel.add(exifBase); cards[cardNo].add(argsPanel, BorderLayout.CENTER); //--------------------------------------------------------------------- @@ -174,8 +203,8 @@ JLabel label3 = new JLabel(); label3.setText("

正確な撮影時刻を入力してください。

"); argsPanel.add(label3); - arg1Panel_3 = new ParameterPanel("  基準時刻: ", ImportPicture.TIME_FORMAT_STRING); - argsPanel.add(arg1Panel_3); + arg3_basetiome = new ParameterPanel("  基準時刻: ", ImportPicture.TIME_FORMAT_STRING); + argsPanel.add(arg3_basetiome); cards[cardNo].add(argsPanel, BorderLayout.NORTH); // 参考画像 @@ -205,8 +234,8 @@ JPanel tmpPanel4 = new JPanel(); tmpPanel4.setLayout(new BoxLayout(tmpPanel4, BoxLayout.Y_AXIS)); File gpxDir = new File("."); - arg1Panel_5 = new ParameterPanelFolder("GPXフォルダ: ", gpxDir.getAbsolutePath()); - tmpPanel4.add(arg1Panel_5); + arg4_gpxFolder = new ParameterPanelFolder("GPXフォルダ: ", gpxDir.getAbsolutePath()); + tmpPanel4.add(arg4_gpxFolder); cards[cardNo].add(tmpPanel4, BorderLayout.CENTER); //--------------------------------------------------------------------- @@ -220,17 +249,12 @@ JPanel tmpPanel5 = new JPanel(); tmpPanel5.setLayout(new BoxLayout(tmpPanel5, BoxLayout.Y_AXIS)); - exifON = new JRadioButton("EXIFの変換をする"); - JRadioButton exifOFF = new JRadioButton("EXIFの変換をしない", true); - ButtonGroup group = new ButtonGroup(); - group.add(exifON); - group.add(exifOFF); - tmpPanel5.add(exifOFF); + exifON = new JCheckBox("EXIFの変換をする", false); tmpPanel5.add(exifON); File outputDir = new File("."); - arg1Panel_4 = new ParameterPanelFolder("書き出しフォルダ: ", outputDir.getAbsolutePath()); - tmpPanel5.add(arg1Panel_4); + arg5_outputFolder = new ParameterPanelFolder("書き出しフォルダ: ", outputDir.getAbsolutePath()); + tmpPanel5.add(arg5_outputFolder); cards[cardNo].add(tmpPanel5, BorderLayout.CENTER); doButton = new JButton("処理実行", AdjustTime.createImageIcon("images/media_playback_start.png")); @@ -267,9 +291,10 @@ openButton.addActionListener(lSymAction); zoomOutButton.addActionListener(lSymAction); zoomInButton.addActionListener(lSymAction); - arg1Panel_2.argField.addActionListener(lSymAction); - arg1Panel_2.openButton.addActionListener(lSymAction); + arg2_baseTimeImg.argField.addActionListener(lSymAction); + arg2_baseTimeImg.openButton.addActionListener(lSymAction); doButton.addActionListener(lSymAction); + exifON.addActionListener(lSymAction); //arg1Panel_4.field.addActionListener(lSymAction); nextButton.addActionListener(lSymAction); backButton.addActionListener(lSymAction); @@ -296,10 +321,15 @@ */ static public void main(String args[]) { SwingUtilities.invokeLater(() -> { - createAndShowGUI(); + try { + createAndShowGUI(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } }); } - private static void createAndShowGUI() { + private static void createAndShowGUI() throws IOException { (new AdjustTime()).setVisible(true); } @@ -347,13 +377,29 @@ * 選択された画像ファイルを表示する * 基準画像ボタンがクリックされた時に、基準時刻フィールドに基準画像の作成日時を設定する。 * @param ev + * @throws ImageReadException + * @throws ImageWriteException */ public void imageView_Action(ActionEvent ev) { - String path = (new File(arg1Panel_1.getText(), arg1Panel_2.getText())).getPath(); + String path = (new File(arg1_srcFolder.getText(), arg2_baseTimeImg.getText())).getPath(); File timeFile = new File(path); long lastModifyTime = timeFile.lastModified(); - arg1Panel_3.argField.setText(ImportPicture.dfjp.format(new Date(lastModifyTime))); + arg3_basetiome.argField.setText(ImportPicture.dfjp.format(new Date(lastModifyTime))); + + try { + ImageMetadata meta = Imaging.getMetadata(timeFile); + if (!(meta instanceof JpegImageMetadata)) { + TiffImageMetadata exif = ((JpegImageMetadata)meta).getExif(); + if (exif != null) { + TiffOutputSet outputSet = exif.getOutputSet(); + TiffOutputDirectory exifDir = outputSet.getOrCreateExifDirectory(); + TiffOutputField field = exifDir.findField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL); + arg3_basetiome.argField.setText(field.toString()); + } + } + } + catch (Exception e) {} int size_x = imageSPane.getWidth() - 8; ImageIcon tmpIcon = new ImageIcon(path); @@ -368,7 +414,7 @@ public void zoomin_Action(ActionEvent ev) { if (refImage != null) { int size_x = imageLabel.getWidth(); - String path = (new File(arg1Panel_1.getText(), arg1Panel_2.getText())).getPath(); + String path = (new File(arg1_srcFolder.getText(), arg2_baseTimeImg.getText())).getPath(); ImageIcon tmpIcon = new ImageIcon(path); refImage = new ImageIcon(tmpIcon.getImage().getScaledInstance(size_x * 2, -1, Image.SCALE_DEFAULT)); imageLabel.setIcon(refImage); @@ -385,12 +431,20 @@ repaint(); } } - + + /** + * ソースディレクトリが選択された時のアクション + * → AdjustTime.ini に書き込む + * @param ev + */ + public void selectSource_Action(ActionEvent ev) { + } + public void selectImage_Action(ActionEvent ev) { JFileChooser fc; //Set up the file chooser. - File sdir = new File(arg1Panel_1.getText()); + File sdir = new File(arg1_srcFolder.getText()); System.out.println(sdir.getPath()); if (sdir.isDirectory()) { fc = new JFileChooser(sdir); @@ -416,7 +470,7 @@ //Process the results. if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); - arg1Panel_2.argField.setText(file.getName()); + arg2_baseTimeImg.argField.setText(file.getName()); } //Reset the file chooser for the next time it's shown. @@ -437,6 +491,16 @@ } /** + * checkbox[EXIF書き出し]を変更した場合のアクション + * ON ー> EXIF変換先フォルダのフィールドを有効にする + * OFF -> EXIF変換先フォルダのフィールドを無効にする + * @param event + */ + void exifON_Action (ActionEvent event) { + arg5_outputFolder.setEnabled(exifON.isEnabled()); + } + + /** * [実行]ボタンをクリックしたときの動作 * @param event */ @@ -444,11 +508,11 @@ doButton.setEnabled(false); String[] argv = new String[5]; - argv[0] = arg1Panel_1.getText(); - argv[1] = arg1Panel_2.getText(); - argv[2] = arg1Panel_3.getText(); - argv[3] = (exifON.isSelected() ? arg1Panel_4.getText() : "noEXIF"); - argv[4] = arg1Panel_5.getText(); + argv[0] = arg1_srcFolder.getText(); + argv[1] = arg2_baseTimeImg.getText(); + argv[2] = arg3_basetiome.getText(); + argv[3] = (exifON.isSelected() ? arg5_outputFolder.getText() : "noEXIF"); + argv[4] = arg4_gpxFolder.getText(); (new DoDialog(this, argv)).setVisible(true); diff --git a/importPicture/src/osm/jp/gpx/matchtime/gui/GpxFilter.java b/importPicture/src/osm/jp/gpx/matchtime/gui/GpxFilter.java new file mode 100644 index 0000000..6261a10 --- /dev/null +++ b/importPicture/src/osm/jp/gpx/matchtime/gui/GpxFilter.java @@ -0,0 +1,28 @@ +package osm.jp.gpx.matchtime.gui; + +import java.io.File; +import javax.swing.filechooser.*; + +public class GpxFilter extends FileFilter { + + public boolean accept(File f) { + if (f.isDirectory()) { + return true; + } + + String extension = Utils.getExtension(f); + if (extension != null) { + if (extension.equals("gpx")) { + return true; + } + else { + return false; + } + } + return false; + } + + public String getDescription() { + return "Just GPXs"; + } +} diff --git a/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanel.java b/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanel.java index 5e4c597..4d7400d 100644 --- a/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanel.java +++ b/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanel.java @@ -11,9 +11,12 @@ * パラメータを設定する為のパネル。 * この1インスタンスで、1パラメータをあらわす。 */ -@SuppressWarnings("serial") public class ParameterPanel extends JPanel { - public JTextField argField; + /** + * + */ + private static final long serialVersionUID = 4629824800747170556L; + public JTextField argField; public JLabel argLabel; public ParameterPanel(String label, String text) { diff --git a/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanelFolder.java b/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanelFolder.java index b6e84e4..31369c4 100644 --- a/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanelFolder.java +++ b/importPicture/src/osm/jp/gpx/matchtime/gui/ParameterPanelFolder.java @@ -9,7 +9,7 @@ @SuppressWarnings("serial") public class ParameterPanelFolder extends ParameterPanel implements ActionListener { JFileChooser fc; - JButton openButton, nextButton; + JButton openButton; public ParameterPanelFolder(String label, String text) { super(label, text); @@ -41,10 +41,13 @@ this.add(openButton); } + public void setEnable(boolean f) { + super.setEnabled(f); + openButton.setEnabled(f); + } + public void actionPerformed(ActionEvent e) { - - //Handle open button action. - if ((e.getSource() == openButton) || (e.getSource() == nextButton)){ + if (e.getSource() == openButton){ int returnVal = fc.showOpenDialog(ParameterPanelFolder.this); if (returnVal == JFileChooser.APPROVE_OPTION) { diff --git a/importPicture/src/osm/jp/gpx/matchtime/gui/QuitDialog.java b/importPicture/src/osm/jp/gpx/matchtime/gui/QuitDialog.java index 26eb088..bbe4df3 100644 --- a/importPicture/src/osm/jp/gpx/matchtime/gui/QuitDialog.java +++ b/importPicture/src/osm/jp/gpx/matchtime/gui/QuitDialog.java @@ -12,7 +12,6 @@ import javax.swing.JFrame; import javax.swing.JLabel; -@SuppressWarnings("serial") public class QuitDialog extends JDialog implements WindowListener { public static final String TITLE = "終了?";