800 lines
42 KiB
Java
800 lines
42 KiB
Java
/*
|
|
* To change this license header, choose License Headers in Project Properties.
|
|
* To change this template file, choose Tools | Templates
|
|
* and open the template in the editor.
|
|
*/
|
|
package bitmapencoder;
|
|
|
|
import static bitmapencoder.BitmapEncoder.deepCopy;
|
|
import static bitmapencoder.BitmapEncoder.isImage;
|
|
import static bitmapencoder.BitmapEncoder.processSelectedFiles;
|
|
import java.awt.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.*;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import javax.imageio.ImageIO;
|
|
import javax.swing.*;
|
|
|
|
/**
|
|
*
|
|
* @author Rodot
|
|
*/
|
|
public class BitmapFrame extends javax.swing.JFrame {
|
|
|
|
BitmapEncoder encoder = new BitmapEncoder();
|
|
final JFileChooser fileChooser = new JFileChooser();
|
|
final JFileChooser multiFileChooser = new JFileChooser();
|
|
private File[] filesSelected = null;
|
|
private String lastSingleDirectory = System.getProperty("user.home");
|
|
private String lastMultiDirectory = System.getProperty("user.home");
|
|
private byte multiFormattingSetting = 1;
|
|
private byte singleFormattingSetting = 0;
|
|
private boolean multiWrapSetting = false;
|
|
private boolean singleWrapSetting = true;
|
|
private boolean allowDirectorySelection = false;
|
|
|
|
/**
|
|
* Creates new form BitmapFrame
|
|
*/
|
|
private BitmapFrame() {
|
|
initComponents();
|
|
try {
|
|
loadSettingsFromDisk();
|
|
} catch (IOException ex) {
|
|
Logger.getLogger(BitmapFrame.class.getName()).
|
|
log(Level.SEVERE, null, ex);
|
|
}
|
|
formattingBox.setSelectedIndex((int) singleFormattingSetting);
|
|
encoder.setHexFormatting(formattingBox.getSelectedIndex() == 1);
|
|
wrapCheckbox.setSelected(singleWrapSetting);
|
|
encoder.setWrapping(wrapCheckbox.isSelected());
|
|
allowDirectorySelectionCheckBox.setSelected(allowDirectorySelection);
|
|
File singleDirectory = new File(lastSingleDirectory);
|
|
if (!singleDirectory.exists()) {
|
|
lastSingleDirectory = System.getProperty("user.home");
|
|
}
|
|
fileChooser.setCurrentDirectory(new File(lastSingleDirectory));
|
|
File multiDirectory = new File(lastMultiDirectory);
|
|
if (!multiDirectory.exists()) {
|
|
lastMultiDirectory = System.getProperty("user.home");
|
|
}
|
|
multiFileChooser.setCurrentDirectory(new File(lastMultiDirectory));
|
|
}
|
|
|
|
/**
|
|
* This method is called from within the constructor to initialize the form.
|
|
* WARNING: Do NOT modify this code. The content of this method is always
|
|
* regenerated by the Form Editor.
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
|
private void initComponents() {
|
|
|
|
buttonGroup1 = new javax.swing.ButtonGroup();
|
|
jPanel1 = new javax.swing.JPanel();
|
|
openButton = new javax.swing.JButton();
|
|
message = new javax.swing.JLabel();
|
|
originalPanel = new javax.swing.JPanel();
|
|
original = new javax.swing.JLabel();
|
|
previewPanel = new javax.swing.JPanel();
|
|
preview = new javax.swing.JLabel();
|
|
thresholdSlider = new javax.swing.JSlider();
|
|
FileSelectionPanel = new javax.swing.JPanel();
|
|
singleFileModeRadioButton = new javax.swing.JRadioButton();
|
|
multiFileModeRadioButton = new javax.swing.JRadioButton();
|
|
allowDirectorySelectionCheckBox = new javax.swing.JCheckBox();
|
|
jPanel2 = new javax.swing.JPanel();
|
|
outputScrollPane = new javax.swing.JScrollPane();
|
|
outputTextArea = new javax.swing.JTextArea();
|
|
jPanel3 = new javax.swing.JPanel();
|
|
scaleSlider = new javax.swing.JSlider();
|
|
scaleLabel = new javax.swing.JLabel();
|
|
nameTextField = new javax.swing.JTextField();
|
|
nameLabel = new javax.swing.JLabel();
|
|
formattingBox = new javax.swing.JComboBox();
|
|
formattingLabel = new javax.swing.JLabel();
|
|
wrapCheckbox = new javax.swing.JCheckBox();
|
|
wrapLabel = new javax.swing.JLabel();
|
|
|
|
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
|
setTitle("Bitmap Encoder - Gamebuino");
|
|
setMinimumSize(new java.awt.Dimension(600, 502));
|
|
setName("bitmapFrame"); // NOI18N
|
|
setPreferredSize(new java.awt.Dimension(800, 600));
|
|
addWindowListener(new java.awt.event.WindowAdapter() {
|
|
public void windowClosing(java.awt.event.WindowEvent evt) {
|
|
formWindowClosing(evt);
|
|
}
|
|
});
|
|
|
|
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Input"));
|
|
|
|
openButton.setText("Open");
|
|
openButton.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
openButtonActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
message.setText("Please select a file to encode");
|
|
|
|
originalPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
|
originalPanel.setMaximumSize(new java.awt.Dimension(400, 400));
|
|
originalPanel.setMinimumSize(new java.awt.Dimension(120, 120));
|
|
originalPanel.setPreferredSize(new java.awt.Dimension(120, 120));
|
|
|
|
original.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
|
original.setText("original");
|
|
|
|
javax.swing.GroupLayout originalPanelLayout = new javax.swing.GroupLayout(originalPanel);
|
|
originalPanel.setLayout(originalPanelLayout);
|
|
originalPanelLayout.setHorizontalGroup(
|
|
originalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(original, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
|
|
);
|
|
originalPanelLayout.setVerticalGroup(
|
|
originalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(original, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
|
|
);
|
|
|
|
previewPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
|
previewPanel.setMaximumSize(new java.awt.Dimension(400, 400));
|
|
previewPanel.setMinimumSize(new java.awt.Dimension(120, 120));
|
|
previewPanel.setPreferredSize(new java.awt.Dimension(120, 120));
|
|
|
|
preview.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
|
preview.setText("preview");
|
|
|
|
javax.swing.GroupLayout previewPanelLayout = new javax.swing.GroupLayout(previewPanel);
|
|
previewPanel.setLayout(previewPanelLayout);
|
|
previewPanelLayout.setHorizontalGroup(
|
|
previewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(preview, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
|
|
);
|
|
previewPanelLayout.setVerticalGroup(
|
|
previewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(preview, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
|
|
);
|
|
|
|
thresholdSlider.setMaximum(765);
|
|
thresholdSlider.setOrientation(javax.swing.JSlider.VERTICAL);
|
|
thresholdSlider.setToolTipText("Use to adjust the thresold between black and white.");
|
|
thresholdSlider.setValue(384);
|
|
thresholdSlider.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
|
|
thresholdSlider.setMaximumSize(new java.awt.Dimension(20, 32767));
|
|
thresholdSlider.setMinimumSize(new java.awt.Dimension(20, 36));
|
|
thresholdSlider.setPreferredSize(new java.awt.Dimension(20, 150));
|
|
thresholdSlider.addMouseListener(new java.awt.event.MouseAdapter() {
|
|
public void mouseReleased(java.awt.event.MouseEvent evt) {
|
|
thresholdSliderMouseReleased(evt);
|
|
}
|
|
});
|
|
|
|
FileSelectionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("File Selection Mode"));
|
|
FileSelectionPanel.setName(""); // NOI18N
|
|
|
|
buttonGroup1.add(singleFileModeRadioButton);
|
|
singleFileModeRadioButton.setSelected(true);
|
|
singleFileModeRadioButton.setText("Single File Mode");
|
|
singleFileModeRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
singleFileModeRadioButtonActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
buttonGroup1.add(multiFileModeRadioButton);
|
|
multiFileModeRadioButton.setText("Multi File Mode (disables preview)");
|
|
multiFileModeRadioButton.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
multiFileModeRadioButtonActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
allowDirectorySelectionCheckBox.setText("Allow directory selection");
|
|
allowDirectorySelectionCheckBox.setEnabled(false);
|
|
allowDirectorySelectionCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
allowDirectorySelectionCheckBoxActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
javax.swing.GroupLayout FileSelectionPanelLayout = new javax.swing.GroupLayout(FileSelectionPanel);
|
|
FileSelectionPanel.setLayout(FileSelectionPanelLayout);
|
|
FileSelectionPanelLayout.setHorizontalGroup(
|
|
FileSelectionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(FileSelectionPanelLayout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(FileSelectionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(FileSelectionPanelLayout.createSequentialGroup()
|
|
.addGap(21, 21, 21)
|
|
.addComponent(allowDirectorySelectionCheckBox))
|
|
.addComponent(singleFileModeRadioButton)
|
|
.addComponent(multiFileModeRadioButton))
|
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
);
|
|
FileSelectionPanelLayout.setVerticalGroup(
|
|
FileSelectionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(FileSelectionPanelLayout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addComponent(singleFileModeRadioButton)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(multiFileModeRadioButton)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(allowDirectorySelectionCheckBox)
|
|
.addContainerGap(8, Short.MAX_VALUE))
|
|
);
|
|
|
|
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
|
jPanel1.setLayout(jPanel1Layout);
|
|
jPanel1Layout.setHorizontalGroup(
|
|
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
|
.addComponent(originalPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(previewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addComponent(FileSelectionPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
|
.addComponent(openButton)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
.addComponent(message)))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
.addComponent(thresholdSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addContainerGap())
|
|
);
|
|
jPanel1Layout.setVerticalGroup(
|
|
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
|
.addGap(45, 45, 45)
|
|
.addComponent(thresholdSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addGroup(jPanel1Layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addComponent(FileSelectionPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
.addComponent(openButton)
|
|
.addComponent(message, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(originalPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addComponent(previewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
);
|
|
|
|
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Output"));
|
|
|
|
outputScrollPane.setFont(new java.awt.Font("Monospaced", 0, 11)); // NOI18N
|
|
outputScrollPane.setPreferredSize(new java.awt.Dimension(200, 200));
|
|
|
|
outputTextArea.setColumns(20);
|
|
outputTextArea.setFont(new java.awt.Font("Consolas", 0, 10)); // NOI18N
|
|
outputTextArea.setRows(5);
|
|
outputTextArea.setAutoscrolls(false);
|
|
outputScrollPane.setViewportView(outputTextArea);
|
|
|
|
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
|
|
jPanel2.setLayout(jPanel2Layout);
|
|
jPanel2Layout.setHorizontalGroup(
|
|
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(outputScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE)
|
|
);
|
|
jPanel2Layout.setVerticalGroup(
|
|
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(outputScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
);
|
|
|
|
jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Settings"));
|
|
|
|
scaleSlider.setMaximum(4);
|
|
scaleSlider.setMinimum(1);
|
|
scaleSlider.setMinorTickSpacing(1);
|
|
scaleSlider.setPaintLabels(true);
|
|
scaleSlider.setPaintTicks(true);
|
|
scaleSlider.setSnapToTicks(true);
|
|
scaleSlider.setValue(2);
|
|
scaleSlider.setMaximumSize(new java.awt.Dimension(150, 31));
|
|
scaleSlider.setMinimumSize(new java.awt.Dimension(150, 31));
|
|
scaleSlider.setPreferredSize(new java.awt.Dimension(150, 31));
|
|
scaleSlider.addChangeListener(new javax.swing.event.ChangeListener() {
|
|
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
|
scaleSliderStateChanged(evt);
|
|
}
|
|
});
|
|
|
|
scaleLabel.setText("Preview scale");
|
|
|
|
nameTextField.setFont(new java.awt.Font("Consolas", 0, 11)); // NOI18N
|
|
nameTextField.setText("bitmapName");
|
|
|
|
nameLabel.setText("Bitmap name");
|
|
|
|
formattingBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Binary (ex: B00110010)", "Hexadecimal (ex: 0x32)" }));
|
|
formattingBox.setName(""); // NOI18N
|
|
formattingBox.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
formattingBoxActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
formattingLabel.setText("Output number formatting");
|
|
|
|
wrapCheckbox.setSelected(true);
|
|
wrapCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
wrapCheckboxActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
wrapLabel.setText("Wrap output lines");
|
|
|
|
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
|
|
jPanel3.setLayout(jPanel3Layout);
|
|
jPanel3Layout.setHorizontalGroup(
|
|
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel3Layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
|
.addComponent(wrapCheckbox)
|
|
.addComponent(formattingBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
.addComponent(nameTextField, javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(scaleSlider, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel3Layout.createSequentialGroup()
|
|
.addComponent(scaleLabel)
|
|
.addGap(0, 0, Short.MAX_VALUE))
|
|
.addGroup(jPanel3Layout.createSequentialGroup()
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(nameLabel)
|
|
.addComponent(formattingLabel)
|
|
.addComponent(wrapLabel))
|
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
|
);
|
|
jPanel3Layout.setVerticalGroup(
|
|
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(jPanel3Layout.createSequentialGroup()
|
|
.addComponent(scaleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))
|
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
|
|
.addComponent(scaleSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addGap(8, 8, 8)))
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addComponent(nameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(formattingLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addComponent(formattingBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
.addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
|
.addComponent(wrapCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
.addComponent(wrapLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
.addContainerGap())
|
|
);
|
|
|
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
|
getContentPane().setLayout(layout);
|
|
layout.setHorizontalGroup(
|
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
.addContainerGap())
|
|
);
|
|
layout.setVerticalGroup(
|
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
|
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addGap(0, 98, Short.MAX_VALUE)))
|
|
.addContainerGap())
|
|
);
|
|
|
|
getAccessibleContext().setAccessibleDescription("");
|
|
|
|
pack();
|
|
}// </editor-fold>//GEN-END:initComponents
|
|
|
|
private void scaleSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_scaleSliderStateChanged
|
|
if (singleFileModeRadioButton.isSelected()) {
|
|
redrawPreview();
|
|
}
|
|
}//GEN-LAST:event_scaleSliderStateChanged
|
|
|
|
private void formattingBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_formattingBoxActionPerformed
|
|
encoder.setHexFormatting(formattingBox.getSelectedIndex() == 1);
|
|
if (singleFileModeRadioButton.isSelected()) {
|
|
singleFormattingSetting = (byte) formattingBox.getSelectedIndex();
|
|
updateOutput();
|
|
} else {
|
|
multiFormattingSetting = (byte) formattingBox.getSelectedIndex();
|
|
processMultiFiles();
|
|
}
|
|
}//GEN-LAST:event_formattingBoxActionPerformed
|
|
|
|
private void wrapCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_wrapCheckboxActionPerformed
|
|
encoder.setWrapping(wrapCheckbox.isSelected());
|
|
if (singleFileModeRadioButton.isSelected()) {
|
|
singleWrapSetting = wrapCheckbox.isSelected();
|
|
updateOutput();
|
|
} else {
|
|
multiWrapSetting = wrapCheckbox.isSelected();;
|
|
processMultiFiles();
|
|
}
|
|
}//GEN-LAST:event_wrapCheckboxActionPerformed
|
|
|
|
private void thresholdSliderMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_thresholdSliderMouseReleased
|
|
if (encoder.getInputImage() == null && singleFileModeRadioButton.isSelected()) {
|
|
message.setText("Open a image before you play with that slider!");
|
|
} else if (singleFileModeRadioButton.isSelected()) {
|
|
message.setText("Loading...");
|
|
redrawPreview();
|
|
message.setText("Output updated");
|
|
} else if (multiFileModeRadioButton.isSelected()) {
|
|
processMultiFiles();
|
|
}
|
|
}//GEN-LAST:event_thresholdSliderMouseReleased
|
|
|
|
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
|
|
if (singleFileModeRadioButton.isSelected()) {
|
|
int returnVal = fileChooser.showOpenDialog(BitmapFrame.this);
|
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
|
lastSingleDirectory = fileChooser.getCurrentDirectory().
|
|
getAbsolutePath();
|
|
File file = fileChooser.getSelectedFile();
|
|
encoder.open(file);
|
|
if (encoder.getInputImage() == null) {
|
|
message.setText("Can't open the selected image");
|
|
} else {
|
|
message.setText("Image succesfully loaded");
|
|
String fileName = file.getName();
|
|
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
|
|
nameTextField.setText(fileName);
|
|
redrawPreview();
|
|
}
|
|
}
|
|
} else {
|
|
|
|
if (allowDirectorySelectionCheckBox.isSelected()) {
|
|
multiFileChooser.setFileSelectionMode(
|
|
JFileChooser.FILES_AND_DIRECTORIES);
|
|
} else {
|
|
multiFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
|
}
|
|
multiFileChooser.setMultiSelectionEnabled(true);
|
|
int returnVal = multiFileChooser.showOpenDialog(this);
|
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
|
lastMultiDirectory = multiFileChooser.getCurrentDirectory().
|
|
getAbsolutePath();
|
|
filesSelected = multiFileChooser.getSelectedFiles();
|
|
processMultiFiles();
|
|
}
|
|
}
|
|
try {
|
|
saveSettingsToDisk(new File("settings.dat"));
|
|
} catch (IOException ex) {
|
|
Logger.getLogger(BitmapFrame.class.getName()).
|
|
log(Level.SEVERE, null, ex);
|
|
}
|
|
}//GEN-LAST:event_openButtonActionPerformed
|
|
|
|
private void processMultiFiles() {
|
|
outputTextArea.setText("");
|
|
String eol = System.lineSeparator();
|
|
File[] filesToConvert = processSelectedFiles(filesSelected, false);
|
|
if (filesToConvert == null) {
|
|
return;
|
|
}
|
|
for (File f : filesToConvert) {
|
|
if (f != null) {
|
|
if (isImage(f)) {
|
|
try {
|
|
System.out.println("Reading image " + f.getName()
|
|
+ "...");
|
|
BufferedImage img = ImageIO.read(f);
|
|
if (img != null) {
|
|
if ((img.getWidth() > 200) || (img.getHeight()
|
|
> 200)) {
|
|
System.out.println("File " + f.getName()
|
|
+ " is too large.");
|
|
continue;
|
|
}
|
|
System.out.println("Deep copy of " + f.getName()
|
|
+ ".");
|
|
BufferedImage newImg = deepCopy(img);
|
|
int threshold = thresholdSlider.getValue();
|
|
System.out.println(
|
|
"Setting threshold for new image.");
|
|
for (int y = 0; y < img.getHeight(); y++) {
|
|
for (int x = 0; x < img.getWidth(); x++) {
|
|
int rgb = img.getRGB(x, y);
|
|
int red = (rgb >> 16) & 0x000000FF;
|
|
int green = (rgb >> 8) & 0x000000FF;
|
|
int blue = (rgb) & 0x000000FF;
|
|
int value = red + green + blue;
|
|
if (value > threshold) {
|
|
newImg.setRGB(x, y, 0x00FFFFFF);
|
|
} else {
|
|
newImg.setRGB(x, y, 0);
|
|
}
|
|
}
|
|
}
|
|
String bitmapName = f.getName().substring(0, f.
|
|
getName().lastIndexOf("."));
|
|
System.out.println("Generating output for " + f.
|
|
getName() + ".");
|
|
String output = outputTextArea.getText();
|
|
output = output.concat("const byte ");
|
|
output = output.concat(bitmapName);
|
|
output = output.concat("[] PROGMEM = {");
|
|
if (encoder.isWrapping()) {
|
|
output = output.concat(eol);
|
|
}
|
|
int width = ((img.getWidth() - 1) / 8 + 1) * 8; //round to the closest larger multiple of 8
|
|
output = output.concat(width + "," + img.
|
|
getHeight() + ",");
|
|
if (encoder.isWrapping()) {
|
|
output = output.concat(eol);
|
|
}
|
|
for (int y = 0; y < img.getHeight(); y++) {
|
|
for (int x = 0; x < img.getWidth(); x += 8) {
|
|
if (encoder.isHexFormatting()) {
|
|
output = output.concat("0x");
|
|
} else {
|
|
output = output.concat("B");
|
|
}
|
|
int thisByte = 0;
|
|
for (int b = 0; b < 8; b++) {
|
|
int value = 0xFFFF;
|
|
if (x + b < img.getWidth()) {
|
|
int rgb = img.getRGB(x + b, y);
|
|
int red = (rgb >> 16)
|
|
& 0x000000FF;
|
|
int green = (rgb >> 8)
|
|
& 0x000000FF;
|
|
int blue = (rgb) & 0x000000FF;
|
|
value = red + green + blue;
|
|
}
|
|
if (encoder.isHexFormatting()) {
|
|
thisByte *= 2;
|
|
if (value < threshold) {
|
|
thisByte++;
|
|
}
|
|
} else {//binary formatting
|
|
if (value < threshold) {
|
|
output = output.concat("1");
|
|
} else {
|
|
output = output.concat("0");
|
|
}
|
|
|
|
}
|
|
}
|
|
if (encoder.isHexFormatting()) {
|
|
output = output.concat(Integer.
|
|
toString(thisByte, 16).
|
|
toUpperCase());
|
|
}
|
|
output = output.concat(",");
|
|
}
|
|
if (encoder.isWrapping()) {
|
|
output = output.concat(eol);
|
|
}
|
|
}
|
|
output = output.concat("};" + eol);
|
|
if (encoder.isWrapping()) {
|
|
output = output.concat(eol);
|
|
}
|
|
outputTextArea.setText(output);
|
|
}
|
|
} catch (IOException ex) {
|
|
Logger.getLogger(BitmapFrame.class.
|
|
getName()).
|
|
log(Level.SEVERE, null, ex);
|
|
}
|
|
} else {
|
|
System.out.println("File " + f.getName()
|
|
+ " is not an image.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private void singleFileModeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_singleFileModeRadioButtonActionPerformed
|
|
scaleSlider.setEnabled(true);
|
|
nameTextField.setEnabled(true);
|
|
allowDirectorySelectionCheckBox.setEnabled(false);
|
|
formattingBox.setSelectedIndex((int) singleFormattingSetting);
|
|
encoder.setHexFormatting(formattingBox.getSelectedIndex() == 1);
|
|
wrapCheckbox.setSelected(singleWrapSetting);
|
|
encoder.setWrapping(wrapCheckbox.isSelected());
|
|
updateOutput();
|
|
}//GEN-LAST:event_singleFileModeRadioButtonActionPerformed
|
|
|
|
private void multiFileModeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_multiFileModeRadioButtonActionPerformed
|
|
scaleSlider.setEnabled(false);
|
|
nameTextField.setEnabled(false);
|
|
allowDirectorySelectionCheckBox.setEnabled(true);
|
|
formattingBox.setSelectedIndex((int) multiFormattingSetting);
|
|
encoder.setHexFormatting(formattingBox.getSelectedIndex() == 1);
|
|
wrapCheckbox.setSelected(multiWrapSetting);
|
|
encoder.setWrapping(wrapCheckbox.isSelected());
|
|
processMultiFiles();
|
|
}//GEN-LAST:event_multiFileModeRadioButtonActionPerformed
|
|
|
|
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
|
|
try {
|
|
saveSettingsToDisk(new File("settings.dat"));
|
|
} catch (IOException ex) {
|
|
Logger.getLogger(BitmapFrame.class.getName()).
|
|
log(Level.SEVERE, null, ex);
|
|
}
|
|
}//GEN-LAST:event_formWindowClosing
|
|
|
|
private void allowDirectorySelectionCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allowDirectorySelectionCheckBoxActionPerformed
|
|
allowDirectorySelection = allowDirectorySelectionCheckBox.isSelected();
|
|
}//GEN-LAST:event_allowDirectorySelectionCheckBoxActionPerformed
|
|
|
|
/**
|
|
* @param args the command line arguments
|
|
*/
|
|
public static void main(String args[]) {
|
|
/* Set the Nimbus look and feel */
|
|
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
|
|
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
|
|
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
|
|
*/
|
|
try {
|
|
/*for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
|
|
if ("Nimbus".equals(info.getName())) {
|
|
javax.swing.UIManager.setLookAndFeel(info.getClassName());
|
|
break;
|
|
}
|
|
}*/
|
|
javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.
|
|
getSystemLookAndFeelClassName());
|
|
} catch (ClassNotFoundException | InstantiationException |
|
|
IllegalAccessException |
|
|
javax.swing.UnsupportedLookAndFeelException ex) {
|
|
java.util.logging.Logger.getLogger(BitmapFrame.class.getName()).log(
|
|
java.util.logging.Level.SEVERE, null, ex);
|
|
}
|
|
//</editor-fold>
|
|
|
|
/* Create and display the form */
|
|
java.awt.EventQueue.invokeLater(() -> {
|
|
new BitmapFrame().setVisible(true);
|
|
});
|
|
}
|
|
|
|
private void redrawPreview() {
|
|
int scale = scaleSlider.getValue();
|
|
//input image
|
|
Image in = BitmapEncoder.deepCopy(encoder.getInputImage());
|
|
in = in.getScaledInstance(in.getWidth(null) * scale, in.getHeight(null)
|
|
* scale, java.awt.Image.SCALE_REPLICATE);
|
|
ImageIcon originalIcon = new ImageIcon(in);
|
|
original.setText("");
|
|
original.setIcon(originalIcon);
|
|
//output image
|
|
encoder.threshold(thresholdSlider.getValue());
|
|
Image out = BitmapEncoder.deepCopy(encoder.getOutputImage());
|
|
out = out.getScaledInstance(out.getWidth(null) * scale, out.getHeight(
|
|
null) * scale, java.awt.Image.SCALE_REPLICATE);
|
|
ImageIcon previewIcon = new ImageIcon(out);
|
|
preview.setText("");
|
|
preview.setIcon(previewIcon);
|
|
updateOutput();
|
|
}
|
|
|
|
private void updateOutput() {
|
|
encoder.setBitmapName(nameTextField.getText());
|
|
outputTextArea.setText(encoder.
|
|
generateOutput(thresholdSlider.getValue()));
|
|
outputTextArea.setCaretPosition(0);
|
|
}
|
|
|
|
private void loadSettingsFromDisk() throws IOException {
|
|
File saveFile = new File("settings.dat");
|
|
if (saveFile.createNewFile()) {
|
|
saveSettingsToDisk(saveFile);
|
|
} else {
|
|
BufferedReader br = new BufferedReader(new FileReader(saveFile));
|
|
for (String line; (line = br.readLine()) != null;) {
|
|
String settingName = line.trim().substring(0, line.indexOf(":"));
|
|
String setting = line.substring((line.indexOf(":") + 1)).trim();
|
|
switch (settingName) {
|
|
case "LAST_SINGLE_DIRECTORY":
|
|
lastSingleDirectory = setting;
|
|
break;
|
|
case "LAST_MULTI_DIRECTORY":
|
|
lastMultiDirectory = setting;
|
|
break;
|
|
case "SINGLE_FORMATTING":
|
|
singleFormattingSetting = Byte.valueOf(setting);
|
|
break;
|
|
case "MULTI_FORMATTING":
|
|
multiFormattingSetting = Byte.valueOf(setting);
|
|
break;
|
|
case "SINGLE_WRAPPING":
|
|
singleWrapSetting = Boolean.valueOf(setting);
|
|
break;
|
|
case "MULTI_WRAPPING":
|
|
multiWrapSetting = Boolean.valueOf(setting);
|
|
break;
|
|
case "ALLOW_DIRECTORY_SELECTION":
|
|
allowDirectorySelection = Boolean.valueOf(setting);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
// line is not visible here.
|
|
}
|
|
}
|
|
|
|
private void saveSettingsToDisk(File saveFile) throws IOException {
|
|
try (BufferedWriter out = new BufferedWriter(new FileWriter(saveFile))) {
|
|
out.write("LAST_SINGLE_DIRECTORY: " + lastSingleDirectory);
|
|
out.newLine();
|
|
out.write("LAST_MULTI_DIRECTORY: " + lastMultiDirectory);
|
|
out.newLine();
|
|
out.write("SINGLE_FORMATTING: " + singleFormattingSetting);
|
|
out.newLine();
|
|
out.write("MULTI_FORMATTING: " + multiFormattingSetting);
|
|
out.newLine();
|
|
out.write("SINGLE_WRAPPING: " + singleWrapSetting);
|
|
out.newLine();
|
|
out.write("MULTI_WRAPPING: " + multiWrapSetting);
|
|
out.newLine();
|
|
out.write("ALLOW_DIRECTORY_SELECTION: " + allowDirectorySelection);
|
|
out.newLine();
|
|
out.close();
|
|
}
|
|
}
|
|
|
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
|
private javax.swing.JPanel FileSelectionPanel;
|
|
private javax.swing.JCheckBox allowDirectorySelectionCheckBox;
|
|
private javax.swing.ButtonGroup buttonGroup1;
|
|
private javax.swing.JComboBox formattingBox;
|
|
private javax.swing.JLabel formattingLabel;
|
|
private javax.swing.JPanel jPanel1;
|
|
private javax.swing.JPanel jPanel2;
|
|
private javax.swing.JPanel jPanel3;
|
|
private javax.swing.JLabel message;
|
|
private javax.swing.JRadioButton multiFileModeRadioButton;
|
|
private javax.swing.JLabel nameLabel;
|
|
private javax.swing.JTextField nameTextField;
|
|
private javax.swing.JButton openButton;
|
|
private javax.swing.JLabel original;
|
|
private javax.swing.JPanel originalPanel;
|
|
private javax.swing.JScrollPane outputScrollPane;
|
|
private javax.swing.JTextArea outputTextArea;
|
|
private javax.swing.JLabel preview;
|
|
private javax.swing.JPanel previewPanel;
|
|
private javax.swing.JLabel scaleLabel;
|
|
private javax.swing.JSlider scaleSlider;
|
|
private javax.swing.JRadioButton singleFileModeRadioButton;
|
|
private javax.swing.JSlider thresholdSlider;
|
|
private javax.swing.JCheckBox wrapCheckbox;
|
|
private javax.swing.JLabel wrapLabel;
|
|
// End of variables declaration//GEN-END:variables
|
|
}
|