4040import java .awt .*;
4141import java .awt .image .BufferedImage ;
4242import java .awt .image .BufferedImageOp ;
43- import java .io .ByteArrayInputStream ;
44- import java .io .ByteArrayOutputStream ;
4543import java .io .IOException ;
4644import java .net .URI ;
4745import java .nio .file .Path ;
48- import java .util .Arrays ;
4946import java .util .HashMap ;
5047import java .util .Iterator ;
5148import java .util .Map ;
5249import java .util .concurrent .Callable ;
50+ import java .util .regex .Pattern ;
5351
5452class DimensionsConverter implements ITypeConverter <Dimension > {
5553 public Dimension convert (String value ) throws Exception {
@@ -66,6 +64,18 @@ public Dimension convert(String value) throws Exception {
6664 }
6765}
6866
67+ class ColorConverter implements ITypeConverter <Color > {
68+ public Color convert (String value ) throws Exception {
69+ Pattern colorPattern = Pattern .compile ("#[A-F0-9]{6}" );
70+
71+ if (!colorPattern .matcher (value ).matches ()) {
72+ throw new IllegalArgumentException ("Invalid color " + value + ". Must be css color in hexadecimal format #RRGGBB" );
73+ }
74+
75+ return Color .decode (value );
76+ }
77+ }
78+
6979@ Command (name = "qrcode" , mixinStandardHelpOptions = true , version = "qrcode 0.1" , description = "Make a QR code with an overlay image. Inspired by https://hollycummins.com/creating-QR-codes/" )
7080public class main implements Callable <Integer > {
7181
@@ -78,6 +88,9 @@ public class main implements Callable<Integer> {
7888 @ Option (names = { "-o" , "--output" }, description = "Output file" , defaultValue = "qrcode.png" )
7989 Path outPath ;
8090
91+ @ Option (names = { "-qrc" , "--qr-color" }, description = "The qr code color" , defaultValue = "#000000" , converter = ColorConverter .class )
92+ Color qrColor ;
93+
8194 @ Option (names = { "-od" ,
8295 "--overlay-dimensions" }, description = "Dimension to apply to overlay" , converter = DimensionsConverter .class )
8396 Dimension overlayDimensions ;
@@ -89,7 +102,7 @@ public static void main(String[] args) throws Exception {
89102 }
90103
91104 public Integer call () {
92- writeQrCode (text , Path .of ("" ).toUri ().resolve (imagePath ), outPath , 640 );
105+ writeQrCode (text , Path .of ("" ).toUri ().resolve (imagePath ), outPath , 640 , qrColor );
93106
94107 if (outPath .toFile ().exists ()) {
95108 System .out .println ("Created QR code at " + outPath );
@@ -100,7 +113,7 @@ public Integer call() {
100113 return ExitCode .OK ;
101114 }
102115
103- private void writeQrCode (String text , URI imagePath , Path outPath , int width ) {
116+ private void writeQrCode (String text , URI imagePath , Path outPath , int width , Color color ) {
104117 try {
105118 Map <EncodeHintType , ErrorCorrectionLevel > hints = new HashMap <>();
106119
@@ -118,9 +131,8 @@ private void writeQrCode(String text, URI imagePath, Path outPath, int width) {
118131 // Load QR image
119132 BufferedImage qrImage = MatrixToImageWriter .toBufferedImage (bitMatrix ,
120133 new MatrixToImageConfig (
121- 0xFF000000 ,
134+ color . getRGB () ,
122135 0xFFFFFFFF ));
123-
124136 // Initialize combined image
125137 BufferedImage combined = new BufferedImage (qrImage .getHeight (), qrImage .getWidth (),
126138 BufferedImage .TYPE_INT_ARGB );
@@ -142,7 +154,7 @@ private void writeQrCode(String text, URI imagePath, Path outPath, int width) {
142154 }
143155
144156 private static BufferedImage addOverlayImage (Graphics2D g , BufferedImage qrImage ,
145- URI imagePath , Dimension dimensions ) {
157+ URI imagePath , Dimension dimensions ) {
146158
147159 ImageReadParam param = new SVGReadParam ();
148160 param .setSourceRenderSize (new Dimension (400 , 400 ));
@@ -196,8 +208,8 @@ private static BufferedImage readImage(URI imagePath, Dimension dimensions) thro
196208 // scale non-svg by resampling
197209 if (dimensions != null && !"svg" .equals (reader .getFormatName ())) {
198210 BufferedImageOp resampler = new ResampleOp (
199- dimensions .width , dimensions .height ,
200- ResampleOp .FILTER_LANCZOS );
211+ dimensions .width , dimensions .height ,
212+ ResampleOp .FILTER_LANCZOS );
201213 image = resampler .filter (image , null );
202214 }
203215
0 commit comments