From 2cf2d608af862e812e7fd3ac580f869141a96fa7 Mon Sep 17 00:00:00 2001 From: XaviDCR92 Date: Sun, 5 Nov 2017 04:16:32 +0100 Subject: + Added copy of BitmapEncoder + New sprite and unit "Town center" * Provisional collision checking. * Many other modifications. --- .../src/bitmapencoder/BitmapEncoder.java | 224 ++++++ .../src/bitmapencoder/BitmapFrame.form | 530 ++++++++++++++ .../src/bitmapencoder/BitmapFrame.java | 799 +++++++++++++++++++++ 3 files changed, 1553 insertions(+) create mode 100644 BitmapEncoder-master/src/bitmapencoder/BitmapEncoder.java create mode 100644 BitmapEncoder-master/src/bitmapencoder/BitmapFrame.form create mode 100644 BitmapEncoder-master/src/bitmapencoder/BitmapFrame.java (limited to 'BitmapEncoder-master/src/bitmapencoder') diff --git a/BitmapEncoder-master/src/bitmapencoder/BitmapEncoder.java b/BitmapEncoder-master/src/bitmapencoder/BitmapEncoder.java new file mode 100644 index 0000000..3f9601d --- /dev/null +++ b/BitmapEncoder-master/src/bitmapencoder/BitmapEncoder.java @@ -0,0 +1,224 @@ +/* + * 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 java.io.IOException; +import javax.imageio.ImageIO; +import java.io.File; +import java.awt.image.*; + +/** + * + * @author Rodot + */ +public class BitmapEncoder { + + private BufferedImage inputImage; + private BufferedImage outputImage; + private String bitmapName = "myBitmap"; + private boolean hexFormatting = false; + private boolean wrapping = true; + private static File[] filesToConvert; + private static int imageCounter; + private static int fileCount; + + protected void BitmapEncoder() { + } + + protected void open(File file) { + try { + inputImage = ImageIO.read(file); + } catch (IOException e) { + e.printStackTrace(); + } + if (inputImage != null) { + if ((inputImage.getWidth() > 200) || (inputImage.getHeight() > 200)) { + inputImage = null; + return; + } + outputImage = deepCopy(inputImage); + } + } + + protected void threshold(int thres) { + if (inputImage == null) { + return; + } + for (int y = 0; y < inputImage.getHeight(); y++) { + for (int x = 0; x < inputImage.getWidth(); x++) { + int rgb = inputImage.getRGB(x, y); + int red = (rgb >> 16) & 0x000000FF; + int green = (rgb >> 8) & 0x000000FF; + int blue = (rgb) & 0x000000FF; + int value = red + green + blue; + if (value > thres) { + outputImage.setRGB(x, y, 0x00FFFFFF); + } else { + outputImage.setRGB(x, y, 0); + } + } + } + } + + protected String generateOutput(int thres) { + if (inputImage == null) { + return ""; + } + String output = ""; + output = output.concat("const byte "); + output = output.concat(bitmapName); + output = output.concat("[] PROGMEM = {"); + int width = ((inputImage.getWidth() - 1) / 8 + 1) * 8; //round to the closest larger multiple of 8 + output = output.concat(width + "," + inputImage.getHeight() + ","); + if (wrapping) { + output = output.concat("\n"); + } + for (int y = 0; y < inputImage.getHeight(); y++) { + for (int x = 0; x < inputImage.getWidth(); x += 8) { + if (hexFormatting) { + 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 < inputImage.getWidth()) { + int rgb = inputImage.getRGB(x + b, y); + int red = (rgb >> 16) & 0x000000FF; + int green = (rgb >> 8) & 0x000000FF; + int blue = (rgb) & 0x000000FF; + value = red + green + blue; + } + if (hexFormatting) { + thisByte *= 2; + if (value < thres) { + thisByte++; + } + } else {//binary formattning + if (value < thres) { + output = output.concat("1"); + } else { + output = output.concat("0"); + } + + } + } + if (hexFormatting) { + output = output.concat(Integer.toString(thisByte, 16). + toUpperCase()); + } + output = output.concat(","); + } + if (wrapping) { + output = output.concat("\n"); + } + } + output = output.concat("};"); + return output; + } + + protected static BufferedImage deepCopy(BufferedImage bi) { + ColorModel cm = bi.getColorModel(); + boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); + WritableRaster raster = bi.copyData(null); + return new BufferedImage(cm, raster, isAlphaPremultiplied, null); + } + + protected static int countFiles(File[] list, boolean recursed) { + + if (list == null) { + return 0; + } + + if (!recursed) { + fileCount = 0; + } + + for (File f : list) { + if (f.isDirectory()) { + countFiles(f.listFiles(), true); + } else { + if (isImage(f)) { + fileCount++; + } + } + } + return fileCount; + } + + protected static boolean isImage(File f) { + boolean isImage = false; + if (f.getName().endsWith(".bmp") || f.getName().endsWith(".png") + || f.getName().endsWith(".jpeg") + || f.getName().endsWith(".jpg")) { + isImage = true; + } + return isImage; + } + + protected static File[] processSelectedFiles(File[] list, boolean recursed) { + if (!recursed) { + filesToConvert = new File[countFiles(list, false)]; + imageCounter = 0; + } + if (list == null) { + return null; + } + + for (File f : list) { + if (f.isDirectory()) { + processSelectedFiles(f.listFiles(), true); + } else { + if (isImage(f)) { + filesToConvert[imageCounter] = f; + imageCounter++; + } + } + } + return filesToConvert; + } + + protected BufferedImage getInputImage() { + return inputImage; + } + + protected BufferedImage getOutputImage() { + return outputImage; + } + + protected String getBitmapName() { + return bitmapName; + } + + protected boolean isHexFormatting() { + return hexFormatting; + } + + protected boolean isWrapping() { + return wrapping; + } + + protected void setInputImage(BufferedImage inputImage) { + this.inputImage = inputImage; + } + + protected void setOutputImage(BufferedImage outputImage) { + this.outputImage = outputImage; + } + + protected void setBitmapName(String bitmapName) { + this.bitmapName = bitmapName; + } + + protected void setHexFormatting(boolean hexFormatting) { + this.hexFormatting = hexFormatting; + } + + protected void setWrapping(boolean wrapping) { + this.wrapping = wrapping; + } +} diff --git a/BitmapEncoder-master/src/bitmapencoder/BitmapFrame.form b/BitmapEncoder-master/src/bitmapencoder/BitmapFrame.form new file mode 100644 index 0000000..cbf18c6 --- /dev/null +++ b/BitmapEncoder-master/src/bitmapencoder/BitmapFrame.form @@ -0,0 +1,530 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BitmapEncoder-master/src/bitmapencoder/BitmapFrame.java b/BitmapEncoder-master/src/bitmapencoder/BitmapFrame.java new file mode 100644 index 0000000..3bb5af3 --- /dev/null +++ b/BitmapEncoder-master/src/bitmapencoder/BitmapFrame.java @@ -0,0 +1,799 @@ +/* + * 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") + // //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(); + }// //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 */ + // + /* 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); + } + // + + /* 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 +} -- cgit v1.2.3