ClickableBitcoinAddress: Write QR code directly to a JavaFX image, rather than transitioning through a PNG image.

This gets rid of the ZXing-JavaSE dependency.
This commit is contained in:
Sean Gilligan 2019-04-06 13:25:09 -07:00 committed by Andreas Schildbach
parent 560e128458
commit 3538d3342e
2 changed files with 40 additions and 29 deletions

View File

@ -12,7 +12,7 @@ dependencies {
implementation 'com.google.guava:guava:27.1-android' implementation 'com.google.guava:guava:27.1-android'
implementation 'org.fxmisc.easybind:easybind:1.0.3' implementation 'org.fxmisc.easybind:easybind:1.0.3'
implementation 'de.jensd:fontawesomefx:8.0.0' implementation 'de.jensd:fontawesomefx:8.0.0'
implementation 'com.google.zxing:javase:3.3.3' implementation 'com.google.zxing:core:3.3.3'
implementation 'org.slf4j:slf4j-jdk14:1.7.25' implementation 'org.slf4j:slf4j-jdk14:1.7.25'
} }

View File

@ -16,16 +16,10 @@
package wallettemplate.controls; package wallettemplate.controls;
import com.google.zxing.BarcodeFormat; import java.awt.Desktop;
import com.google.zxing.Writer; import java.io.IOException;
import com.google.zxing.WriterException; import java.net.URI;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import org.bitcoinj.core.Address;
import org.bitcoinj.uri.BitcoinURI;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import javafx.beans.binding.StringExpression; import javafx.beans.binding.StringExpression;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -38,20 +32,28 @@ import javafx.scene.control.Tooltip;
import javafx.scene.effect.DropShadow; import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.Clipboard; import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent; import javafx.scene.input.ClipboardContent;
import javafx.scene.input.MouseButton; import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import org.bitcoinj.core.Address;
import org.bitcoinj.uri.BitcoinURI;
import wallettemplate.Main; import wallettemplate.Main;
import wallettemplate.utils.GuiUtils; import wallettemplate.utils.GuiUtils;
import java.awt.*; import com.google.zxing.BarcodeFormat;
import java.io.ByteArrayInputStream; import com.google.zxing.Writer;
import java.io.ByteArrayOutputStream; import com.google.zxing.WriterException;
import java.io.IOException; import com.google.zxing.common.BitMatrix;
import java.net.URI; import com.google.zxing.qrcode.QRCodeWriter;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import static javafx.beans.binding.Bindings.convert; import static javafx.beans.binding.Bindings.convert;
@ -157,18 +159,15 @@ public class ClickableBitcoinAddress extends AnchorPane {
* @return a javafx Image * @return a javafx Image
*/ */
private static Image qrCodeImage(String uri) { private static Image qrCodeImage(String uri) {
// Serialize to PNG and back into an image. Pretty lame but it's the shortest code to write and I'm feeling return toImage(qrCodeMatrix(uri));
// lazy tonight.
byte[] imageBytes = qrCodePNGBytes(uri);
return new Image(new ByteArrayInputStream(imageBytes));
} }
/** /**
* Create a PNG-format image byte string from a Bitcoin URI * Create a BitMatrix from a Bitcoin URI
* @param uri Bitcoin URI * @param uri Bitcoin URI
* @return PNG-format bytes * @return A BitMatrix for the QRCode for the URI
*/ */
private static byte[] qrCodePNGBytes(String uri) { private static BitMatrix qrCodeMatrix(String uri) {
Writer qrWriter = new QRCodeWriter(); Writer qrWriter = new QRCodeWriter();
BitMatrix matrix; BitMatrix matrix;
try { try {
@ -176,12 +175,24 @@ public class ClickableBitcoinAddress extends AnchorPane {
} catch (WriterException e) { } catch (WriterException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
ByteArrayOutputStream stream = new ByteArrayOutputStream(); return matrix;
try { }
MatrixToImageWriter.writeToStream(matrix, "PNG", stream);
} catch (IOException e) { /**
throw new RuntimeException(e); * Create a JavaFX Image from a BitMatrix
* @param matrix the matrix
* @return the QRCode Image
*/
private static Image toImage(BitMatrix matrix) {
int height = matrix.getHeight();
int width = matrix.getWidth();
WritableImage image = new WritableImage(width, height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color color = matrix.get(x,y) ? Color.BLACK : Color.WHITE;
image.getPixelWriter().setColor(x, y, color);
}
} }
return stream.toByteArray(); return image;
} }
} }