1
0
Fork 0

QR-Programm

This commit is contained in:
Ruben Meyer 2020-07-04 12:24:16 +02:00
parent 6cc9b9e973
commit 5481ca8841
Signed by: rxbn_
GPG Key ID: BE3BF898BE352FE2
24 changed files with 844 additions and 0 deletions

8
QR/.classpath Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="lib" path="jgoodies-common-1.8.0.jar" sourcepath="jgoodies-common-1.8.0-sources.jar"/>
<classpathentry kind="lib" path="jgoodies-forms-1.8.0.jar" sourcepath="jgoodies-forms-1.8.0-sources.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

17
QR/.project Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Sven.QR</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

Binary file not shown.

BIN
QR/bin/MainFrame$1.class Normal file

Binary file not shown.

BIN
QR/bin/MainFrame$2.class Normal file

Binary file not shown.

BIN
QR/bin/MainFrame$3.class Normal file

Binary file not shown.

BIN
QR/bin/MainFrame$4.class Normal file

Binary file not shown.

BIN
QR/bin/MainFrame$5.class Normal file

Binary file not shown.

BIN
QR/bin/MainFrame$6.class Normal file

Binary file not shown.

BIN
QR/bin/MainFrame.class Normal file

Binary file not shown.

BIN
QR/bin/Pair.class Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
QR/bin/SvenQR.class Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
QR/jgoodies-forms-1.8.0.jar Normal file

Binary file not shown.

View File

@ -0,0 +1,11 @@
public class BorderInformation {
// Randstärke in Pixeln
public float BorderWidth;
// Erstes schwarzes Pixel in der linken oberen Ecke
public Pair firstBlackPixel;
public BorderInformation(float width, Pair firstBlack) {
BorderWidth = width;
firstBlackPixel = firstBlack;
}
}

227
QR/src/MainFrame.java Normal file
View File

@ -0,0 +1,227 @@
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JMenuBar;
import javax.swing.JTabbedPane;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JMenu;
import javax.swing.KeyStroke;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.event.InputEvent;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
import com.jgoodies.forms.factories.DefaultComponentFactory;
import javax.swing.JTextField;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JCheckBox;
public class MainFrame extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTextField textField_1;
JButton btnEinlesen = new JButton("Einlesen");
JLabel lblNewLabel = new JLabel("Ausgelesener Wert: -");
JButton btnDrucken = new JButton("Drucken");
JButton btnSpeichern = new JButton("Speichern");
// Parent für JFileChooser
JFrame _this = this;
// File zum speichern / lesen
File f;
// Generierter QR-Code
BufferedImage img = null;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
MainFrame frame = new MainFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MainFrame() {
setTitle("Sven.QR");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 600, 400);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
contentPane.add(tabbedPane, BorderLayout.CENTER);
JPanel panel_1 = new JPanel();
tabbedPane.addTab(" QR-Code generieren ", null, panel_1, null);
panel_1.setLayout(null);
JLabel lblQrcode = new JLabel("QR-Code Wert:");
lblQrcode.setBounds(10, 14, 80, 14);
panel_1.add(lblQrcode);
textField_1 = new JTextField();
textField_1.setBounds(94, 11, 424, 20);
panel_1.add(textField_1);
textField_1.setColumns(10);
//
// = BUTTON GENERIEREN: Generiert einen QR-Code aus dem Wert der TextBox und speichert ihn.
//
JButton btnGenerieren = new JButton("Generieren");
btnGenerieren.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
int value = Integer.parseInt(textField_1.getText());
img = SvenQR.GenerateQR(value);
} catch(Exception e1) {
JOptionPane.showMessageDialog(_this, "QR-Code konnte nicht generiert werden: " + e1.getMessage());
return;
}
btnDrucken.setEnabled(true);
btnSpeichern.setEnabled(true);
}
});
btnGenerieren.setBounds(94, 42, 89, 23);
panel_1.add(btnGenerieren);
//
// = BUTTON DRUCKEN: Druckt den generierten QR-Code.
//
btnDrucken.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Thread(new PrintActionListener(img)).start();
}
});
btnDrucken.setEnabled(false);
btnDrucken.setBounds(292, 42, 89, 23);
panel_1.add(btnDrucken);
//
// = BUTTON SPEICHERN: Speichert den generierten QR-Code.
//
btnSpeichern.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// JFileChooser erstellen
JFileChooser fc = new JFileChooser();
// Dateifilter setzen
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"PNG (*.png)", "png");
fc.setFileFilter(filter);
// Wenn im Dialog nicht OK gedrückt wurde, Methode verlassen
if (fc.showSaveDialog(_this) != JFileChooser.APPROVE_OPTION)
return;
f = fc.getSelectedFile();
try {
ImageIO.write(img, "png", f);
} catch (IOException e1) {
JOptionPane.showMessageDialog(_this, "QR-Code konnte nicht gespeichert werden: " + e1.getMessage());
return;
}
}
});
btnSpeichern.setEnabled(false);
btnSpeichern.setBounds(193, 42, 89, 23);
panel_1.add(btnSpeichern);
JPanel panel = new JPanel();
tabbedPane.addTab(" QR-Code einlesen ", null, panel, null);
panel.setLayout(null);
JLabel lblQuelldatei = new JLabel("Quelldatei:");
lblQuelldatei.setBounds(10, 12, 55, 14);
panel.add(lblQuelldatei);
textField = new JTextField();
textField.setBounds(75, 8, 451, 21);
panel.add(textField);
textField.setColumns(10);
//
// = BUTTON ... : Wählt die Quelldatei mit einem JFileChooser aus. =
//
JButton button = new JButton("...");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// JFileChooser erstellen
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File("T:/INTABI19/Projekt/ELMO Interactive Toolbox/rec"));
// Wenn im Dialog nicht OK gedrückt wurde, Methode verlassen
if (fc.showOpenDialog(_this) != JFileChooser.APPROVE_OPTION)
return;
// Ausgewählte Datei auslesen
f = fc.getSelectedFile();
// Pfad der Datei in Textbox schreiben
textField.setText(f.getAbsolutePath());
// Einlesen-Button aktivieren
btnEinlesen.setEnabled(true);
}
});
button.setBounds(536, 7, 23, 23);
panel.add(button);
//
// = BUTTON EINLESEN: Liest ausgewählten QR-Code aus Datei ein. =
//
btnEinlesen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Ausgelesener Wert
int value = -1;
// Versuche, den QR-Code einzulesen
// Wenn das nicht geht, wird eine Fehlermeldung ausgegeben
try {
value = SvenQR.ReadQR(f.getAbsolutePath());
} catch (IOException e1) {
JOptionPane.showMessageDialog(_this, "QR-Code konnte nicht eingelesen werden: " + e1.getMessage());
return;
}
// Ausgelesener Wert auf Label schreiben
lblNewLabel.setText("Ausgelesener Wert: " + value);
}
});
btnEinlesen.setEnabled(false);
btnEinlesen.setBounds(75, 40, 89, 23);
panel.add(btnEinlesen);
lblNewLabel.setBounds(10, 74, 549, 14);
panel.add(lblNewLabel);
}
}

15
QR/src/Pair.java Normal file
View File

@ -0,0 +1,15 @@
public class Pair {
public int x, y;
public Pair(int _x, int _y) {
x = _x;
y = _y;
}
// Kopierkonstruktor, da eine Zuweisung nicht die Werte kopiert,
// sondern beide Variablen auf den gleichen Speicher zeigen lässt.
public Pair(Pair copy) {
x = copy.x;
y = copy.y;
}
}

View File

@ -0,0 +1,71 @@
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
// Quelle: https://stackoverflow.com/questions/18404553/proper-way-of-printing-a-bufferedimage-in-java
public class PrintActionListener implements Runnable {
private BufferedImage image;
public PrintActionListener(BufferedImage image) {
this.image = image;
}
@Override
public void run() {
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(new ImagePrintable(printJob, image));
if (printJob.printDialog()) {
try {
printJob.print();
} catch (PrinterException prt) {
prt.printStackTrace();
}
}
}
public class ImagePrintable implements Printable {
private double x, y, width;
private int orientation;
private BufferedImage image;
public ImagePrintable(PrinterJob printJob, BufferedImage image) {
PageFormat pageFormat = printJob.defaultPage();
this.x = pageFormat.getImageableX();
this.y = pageFormat.getImageableY();
this.width = pageFormat.getImageableWidth();
this.orientation = pageFormat.getOrientation();
this.image = image;
}
@Override
public int print(Graphics g, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if (pageIndex == 0) {
int pWidth = 0;
int pHeight = 0;
if (orientation == PageFormat.PORTRAIT) {
pWidth = (int) Math.min(width, (double) image.getWidth());
pHeight = pWidth * image.getHeight() / image.getWidth();
} else {
pHeight = (int) Math.min(width, (double) image.getHeight());
pWidth = pHeight * image.getWidth() / image.getHeight();
}
g.drawImage(image, (int) x, (int) y, pWidth, pHeight, null);
return PAGE_EXISTS;
} else {
return NO_SUCH_PAGE;
}
}
}
}

484
QR/src/SvenQR.java Normal file
View File

@ -0,0 +1,484 @@
import java.awt.*;
import java.awt.image.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.*;
import javax.imageio.ImageIO;
public class SvenQR {
// Anzahl der Rechtecke horizontal
public static final int AMNT_RECT_X = 4;
// Anzahl der Rechtecke vertikal
public static final int AMNT_RECT_Y = 3;
// Rahmendicke in Pixeln
public static final int BORDER_WIDTH = 8;
// Rechteckgröße in Pixeln
public static final int RECT_WIDTH = 40;
// Liest das angegebene Bild ein und wertet den QR-Code aus.
public static int ReadQR(String fileName) throws IOException {
// Quellbild
BufferedImage img = ImageIO.read(new File(fileName));
// Informationen über den Rand und die Ausmaße
BorderInformation info;
// Gemessene Größe des QR-Codes
Pair measuredSize;
// Wert des QR-Codes
int value;
img = _IN_PrepareImage(img);
info = _IN_GetBorderWidth(img);
Pair imageSize = new Pair((int) img.getWidth(), (int) img.getHeight());
measuredSize = _IN_GetMeasuredSize(img, info, imageSize);
// Durchschnittsgröße der Rechtecke
int avgSquareWidth = (int) ((measuredSize.x - 4f * info.BorderWidth) / AMNT_RECT_X);
int avgSquareHeight = (int) ((measuredSize.y - 4f * info.BorderWidth) / AMNT_RECT_Y);
Pair avgSquareSize = new Pair(avgSquareWidth, avgSquareHeight);
value = _IN_HeuristicDetermination(img, info, avgSquareSize);
return value;
}
public static BufferedImage GenerateQR(int value) {
boolean[][] bits;
BufferedImage img;
// Konvertiere die Zahl in eine Bit-Tabelle, die der QR-Code-Darstellung
// entspricht
bits = _OUT_GetBits(value);
// Generiere Bild
img = _OUT_DrawImage(bits);
return img;
}
public static BufferedImage _IN_PrepareImage(BufferedImage img) {
// Bildgröße auslesen
int width = img.getWidth();
int height = img.getHeight();
//
// = BILD ENTSÄTTIGEN UND KONTRAST SPREIZEN =
//
// Jedes Pixel durchgehen und in Graustufen umwandeln,
// danach den Kontrast spreizen, sodass nur noch schwarze
// und weiße Pixel im Bild sind, anders kann der Algorithmus
// nicht arbeiten.
//
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Aktuelles Pixel auslesen
int value = img.getRGB(x, y);
Color c1 = new Color(value);
// Graustufe berechnen
int grau = (c1.getBlue() + c1.getRed() + c1.getGreen()) / 3;
// Kontrast spreizen
if (grau >= 127) {
grau = 255;
} else {
grau = 0;
}
// Pixel ersetzen
Color c = new Color(grau, grau, grau);
img.setRGB(x, y, c.getRGB());
}
}
/*try {
File fx = new File("X:/ents.png"); // Speicherort
ImageIO.write(img, "png", fx); // Bildformat
} catch (IOException e) {
System.out.println("Error: " + e);
}*/
//
// = ALLEINSTEHENDE PIXEL IM BILD ENTFERNEN =
//
// Wenn das Bild fleckig ist, entstehen einzelne Pixel, die
// den Algorithmus zum auslesen stören können, also werden
// diese entfernt.
//
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
boolean weissAussendrum = true;
// Rechts
if (!(x < width - 1 && img.getRGB(x + 1, y) == -1))
weissAussendrum = false;
// Links
if (!(x > 0 && img.getRGB(x - 1, y) == -1))
weissAussendrum = false;
// Drunter
if (!(y < height - 1 && img.getRGB(x, y + 1) == -1))
weissAussendrum = false;
// Drüber
if (!(y > 0 && img.getRGB(x, y - 1) == -1))
weissAussendrum = false;
// Links oben
if (!(x > 0 && y > 0 && img.getRGB(x - 1, y - 1) == - 1))
weissAussendrum = false;
// Links unten
if (!(x > 0 && y < height - 1 && img.getRGB(x - 1, y + 1) == -1))
weissAussendrum = false;
// Rechts oben
if (!(x < width - 1 && y > 0 && img.getRGB(x + 1, y - 1) == -1))
weissAussendrum = false;
// Rechts unten
if (!(x < width - 1 && y < height - 1 && img.getRGB(x + 1, y + 1) == -1))
weissAussendrum = false;
if (weissAussendrum)
img.setRGB(x, y, -1 );
}
}
/*try {
File fx = new File("X:/prep2.png"); // Speicherort
ImageIO.write(img, "png", fx); // Bildformat
} catch (IOException e) {
System.out.println("Error: " + e);
}*/
return img;
}
private static BorderInformation _IN_GetBorderWidth(BufferedImage img) {
Color pixel;
// Informationen über den Rahmen des QR-Codes
BorderInformation info = null;
// Breite des schwarzen Rahmens und Orientierungspunkte
float borderWidth = -1f;
Pair firstBlackPixel = new Pair(-1, -1);
Pair firstWhitePixel;
//
// = SUCHE DAS ERSTE SCHWARZE PIXEL IN DER LINKEN OBEREN ECKE =
//
// Gehe diagonal durch das Bild auf der Suche nach schwarzen Pixeln
while (!_IN_CompareColors(img.getRGB(firstBlackPixel.x + 1, firstBlackPixel.y + 1), Color.BLACK)) {
firstBlackPixel.x++;
firstBlackPixel.y++;
}
firstBlackPixel.x++;
firstBlackPixel.y++;
// Aufgrund von Ungenauigkeiten beim Drucken, gehen wir drei Pixel in den Rand rein
firstBlackPixel.x += 2;
System.out.println("Suche schwarzes Pixel.");
System.out.println("X: " + firstBlackPixel.x + " Y: " + firstBlackPixel.y + "\n");
// Gehe so weit wie möglich nach oben
while (firstBlackPixel.y > 0
&& _IN_CompareColors(img.getRGB(firstBlackPixel.x, firstBlackPixel.y - 1), Color.BLACK))
firstBlackPixel.y--;
System.out.println("Gehe so weit wie möglich nach oben");
System.out.println("X: " + firstBlackPixel.x + " Y: " + firstBlackPixel.y + "\n");
// Gehe so weit wie möglich nach links
while (firstBlackPixel.x > 0
&& _IN_CompareColors(img.getRGB(firstBlackPixel.x - 1, firstBlackPixel.y), Color.BLACK))
firstBlackPixel.x--;
System.out.println("Gehe so weit wie möglich nach links");
System.out.println("X: " + firstBlackPixel.x + " Y: " + firstBlackPixel.y + "\n");
//
// = SUCHE DAS ERSTE WEISSE PIXEL VOM INNEREN RAHMEN =
//
firstWhitePixel = new Pair(firstBlackPixel);
// Gehe diagonal vom ersten schwarzen Pixel durch das Bild
while (!_IN_CompareColors(img.getRGB(firstWhitePixel.x + 1, firstWhitePixel.y + 1), Color.WHITE)) {
firstWhitePixel.x++;
firstWhitePixel.y++;
}
firstWhitePixel.x++;
firstWhitePixel.y++;
System.out.println("Suche weißes Pixel");
System.out.println("X: " + firstWhitePixel.x + " Y: " + firstWhitePixel.y + "\n");
// Gehe so weit wie möglich nach oben
while (_IN_CompareColors(img.getRGB(firstWhitePixel.x, firstWhitePixel.y - 1), Color.WHITE))
firstWhitePixel.y--;
System.out.println("Gehe soweit wie möglich nach oben");
System.out.println("X: " + firstWhitePixel.x + " Y: " + firstWhitePixel.y + "\n");
// Gehe so weit wie möglich nach links
while (_IN_CompareColors(img.getRGB(firstWhitePixel.x - 1, firstWhitePixel.y), Color.WHITE))
firstWhitePixel.x--;
System.out.println("Gehe soweit wie möglich nach links");
System.out.println("X: " + firstWhitePixel.x + " Y: " + firstWhitePixel.y + "\n");
// Differenzen, also Rahmenstärke ausrechnen
int deltaX = firstWhitePixel.x - firstBlackPixel.x;
int deltaY = firstWhitePixel.y - firstBlackPixel.y;
// Durchschnitt ermitteln
borderWidth = (deltaX + deltaY) / 2f;
System.out.println("Border width: " + borderWidth);
info = new BorderInformation(borderWidth, firstBlackPixel);
return info;
}
private static Pair _IN_GetMeasuredSize(BufferedImage img, BorderInformation borderInfo, Pair imageSize) {
Pair measuredSize;
Pair upperRightBlackPixel, lowerLeftBlackPixel;
Color pixel;
//
// = MESSE DIE BREITE DES QR-CODES =
//
upperRightBlackPixel = new Pair(borderInfo.firstBlackPixel);
// Weil das Bild nicht immer gerade ist, messen wir in der Mitte des
// schwarzen Rahmens
upperRightBlackPixel.y += borderInfo.BorderWidth / 2f;
while (upperRightBlackPixel.x < imageSize.x - 1
&& !_IN_CompareColors(img.getRGB(upperRightBlackPixel.x + 1, upperRightBlackPixel.y), Color.WHITE))
upperRightBlackPixel.x++;
//
// = MESSE DIE HÖHE DES QR-CODES =
//
lowerLeftBlackPixel = new Pair(borderInfo.firstBlackPixel);
// Immer mittig messen, kann bei arg schiefen Bildern jedoch auch wieder
// zu fehlerhaften Ergebnissen führen
// In solch einem Fall können wir nichts tun :/
lowerLeftBlackPixel.x += borderInfo.BorderWidth / 2f;
while (lowerLeftBlackPixel.y < imageSize.y - 1
&& !_IN_CompareColors(img.getRGB(upperRightBlackPixel.x, upperRightBlackPixel.y + 1), Color.WHITE))
lowerLeftBlackPixel.y++;
// Errechne die Größe des QR-Codes aus den Differenzen der Punkte
measuredSize = new Pair(upperRightBlackPixel.x - borderInfo.firstBlackPixel.x,
lowerLeftBlackPixel.y - borderInfo.firstBlackPixel.y);
measuredSize.x++;
measuredSize.y++;
System.out.println("Gemessene Größe: " + measuredSize.x + " x " + measuredSize.y);
return measuredSize;
}
private static int _IN_HeuristicDetermination(BufferedImage img, BorderInformation borderInfo, Pair avgSquareSize) {
boolean[][] bits = new boolean[AMNT_RECT_X][AMNT_RECT_Y];
float halfWidth = avgSquareSize.x / 2f, halfHeight = avgSquareSize.y / 2f;
int c_value;
for (int x = 0; x < AMNT_RECT_X; x++) {
for (int y = 0; y < AMNT_RECT_Y; y++) {
int _x = (int) (2 * borderInfo.BorderWidth);
_x += (int) (x * avgSquareSize.x);
_x += (int) halfWidth;
_x += borderInfo.firstBlackPixel.x;
int _y = (int) (2 * borderInfo.BorderWidth);
_y += (int) (y * avgSquareSize.y);
_y += (int) halfHeight;
_y += borderInfo.firstBlackPixel.y;
c_value = img.getRGB(_x, _y);
System.out.println("X: " + _x + " Y: " + _y + " V: " + (_IN_CompareColors(c_value, Color.WHITE) ? false : true));
if (_IN_CompareColors(c_value, Color.WHITE))
bits[x][y] = false;
else if (_IN_CompareColors(c_value, Color.BLACK))
bits[x][y] = true;
}
}
int value = 0;
if (bits[0][0])
value += 1;
if (bits[1][0])
value += 2;
if (bits[2][0])
value += 4;
if (bits[3][0])
value += 8;
if (bits[0][1])
value += 16;
if (bits[1][1])
value += 32;
if (bits[2][1])
value += 64;
if (bits[3][1])
value += 128;
if (bits[0][2])
value += 256;
if (bits[1][2])
value += 512;
if (bits[2][2])
value += 1024;
if (bits[3][2])
value += 2048;
return value;
}
private static boolean _IN_CompareColors(int rgb, Color template) {
Color c = new Color(rgb);
if (c.getRed() != template.getRed())
return false;
if (c.getGreen() != template.getGreen())
return false;
if (c.getBlue() != template.getBlue())
return false;
return true;
}
private static boolean[][] _OUT_GetBits(int value) {
// Die Bits in QR-Code-Darstellung
boolean[][] bits = new boolean[AMNT_RECT_X][AMNT_RECT_Y];
// Die Bits als Binärstring
String bitsAsString = Integer.toBinaryString(value);
// Anzahl an führenden Nullen für 12-Bit:
int amntLeadingZeros = 12 - bitsAsString.length();
// Stelle führende Nullen voran
for (int i = 0; i < amntLeadingZeros; i++)
bitsAsString = "0" + bitsAsString;
bits[0][0] = bitsAsString.charAt(11) == '0' ? false : true;
bits[1][0] = bitsAsString.charAt(10) == '0' ? false : true;
bits[2][0] = bitsAsString.charAt(9) == '0' ? false : true;
bits[3][0] = bitsAsString.charAt(8) == '0' ? false : true;
bits[0][1] = bitsAsString.charAt(7) == '0' ? false : true;
bits[1][1] = bitsAsString.charAt(6) == '0' ? false : true;
bits[2][1] = bitsAsString.charAt(5) == '0' ? false : true;
bits[3][1] = bitsAsString.charAt(4) == '0' ? false : true;
bits[0][2] = bitsAsString.charAt(3) == '0' ? false : true;
bits[1][2] = bitsAsString.charAt(2) == '0' ? false : true;
bits[2][2] = bitsAsString.charAt(1) == '0' ? false : true;
bits[3][2] = bitsAsString.charAt(0) == '0' ? false : true;
return bits;
}
private static BufferedImage _OUT_DrawImage(boolean[][] bits) {
// Bildgröße
Pair imageSize;
// Bild
BufferedImage img;
// Grafikobjekt zum zeichnen
Graphics2D g;
// Bildbreite und -höhe berechnen
// Bei 72 dpi entspricht 1mm 3px, wir nehmen 2px
imageSize = new Pair(BORDER_WIDTH * 4 + AMNT_RECT_X * RECT_WIDTH, BORDER_WIDTH * 4 + AMNT_RECT_Y * RECT_WIDTH);
// Bild erstellen und Grafikobjekt erstellen
img = new BufferedImage(imageSize.x, imageSize.y, BufferedImage.TYPE_INT_ARGB);
g = img.createGraphics();
//
// = QR-CODE-ZEICHEN =
//
// Äußeren Rahmen zeichnen
g.setColor(Color.BLACK);
g.fillRect(0, 0, imageSize.x, imageSize.y);
// Inneren Rahmen zeichnen
g.setColor(Color.WHITE);
g.fillRect(BORDER_WIDTH, BORDER_WIDTH, imageSize.x - 2 * BORDER_WIDTH, imageSize.y - 2 * BORDER_WIDTH);
g.setColor(Color.BLACK);
// Rechtecke zeichnen
for (int x = 0; x < AMNT_RECT_X; x++) {
for (int y = 0; y < AMNT_RECT_Y; y++) {
int _x = BORDER_WIDTH * 2 + x * RECT_WIDTH;
int _y = BORDER_WIDTH * 2 + y * RECT_WIDTH;
if (!bits[x][y])
continue;
g.fillRect(_x, _y, RECT_WIDTH, RECT_WIDTH);
}
}
// Rechte untere Ecke als Orientierungspunkt entfernen
g.setColor(Color.WHITE);
g.fillRect(imageSize.x - BORDER_WIDTH, imageSize.y - BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH);
return img;
}
}