Permalink
Browse files

[fix] add svg support via batik

which is apache licensed

closes #95
  • Loading branch information...
atomfrede committed Sep 3, 2018
1 parent 6e52800 commit a630af389b9ea3d936866f80e66cdc163111f08e
View
@@ -48,6 +48,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<goals>
@@ -59,6 +60,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<executions>
<execution>
<goals>
View
@@ -49,6 +49,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven-source-plugin.version}</version>
<executions>
<execution>
<goals>
@@ -60,6 +61,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<executions>
<execution>
<goals>
@@ -81,10 +83,22 @@
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svggen</artifactId>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-dom</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,53 @@
package net.glxn.qrgen.javase;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.common.BitMatrix;
import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import java.awt.*;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
class MatrixToSvgWriter {
private MatrixToSvgWriter() {
// private utility class constuctor
}
private static SVGGraphics2D toSvgDocument(BitMatrix matrix, MatrixToImageConfig config) {
int width = matrix.getWidth();
int height = matrix.getHeight();
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
String svgNS = "http://www.w3.org/2000/svg";
Document document = domImpl.createDocument(svgNS, "svg", null);
SVGGraphics2D svgGraphics = new SVGGraphics2D(document);
svgGraphics.setColor(new Color(config.getPixelOffColor()));
svgGraphics.fillRect(0,0, width, height);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (matrix.get(x,y)) {
svgGraphics.setColor(new Color(config.getPixelOnColor()));
svgGraphics.fillRect(x, y, 1, 1);
}
}
}
return svgGraphics;
}
static void writeToPath(BitMatrix matrix, Path file, MatrixToImageConfig matrixToImageConfig) throws IOException {
SVGGraphics2D g2 = toSvgDocument(matrix, matrixToImageConfig);
FileWriter out = new FileWriter(file.toFile());
g2.stream(out);
}
}
@@ -150,6 +150,28 @@ protected void writeToStream(OutputStream stream) throws IOException, WriterExce
MatrixToImageWriter.writeToStream(createMatrix(text), imageType.toString(), stream, matrixToImageConfig);
}
public File svg() {
File file;
try {
file = createTempSvgFile();
MatrixToSvgWriter.writeToPath(createMatrix(text), file.toPath(), matrixToImageConfig);
} catch (Exception e) {
throw new QRGenerationException("Failed to create QR svg from text due to underlying exception", e);
}
return file;
}
public File svg(String name) {
File file;
try {
file = createTempSvgFile(name);
MatrixToSvgWriter.writeToPath(createMatrix(text), file.toPath(), matrixToImageConfig);
} catch (Exception e) {
throw new QRGenerationException("Failed to create QR svg from text due to underlying exception", e);
}
return file;
}
private File createTempSvgFile() throws IOException {
return createTempSvgFile("QRCode");
}
@@ -20,10 +20,12 @@
import java.nio.file.Files;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
public class QRCodeTest {
@Test
public void shouldGetFileFromVCardWithDefaults() throws Exception {
public void shouldGetFileFromVCardWithDefaults() {
VCard johnDoe = new VCard("John Doe")
.setName("John Doe")
.setEmail("john.doe@example.org")
@@ -33,11 +35,13 @@ public void shouldGetFileFromVCardWithDefaults() throws Exception {
.setPhoneNumber("1234")
.setWebsite("www.example.org");
File file = QRCode.from(johnDoe).file();
Assert.assertNotNull(file);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetFileFromVCardWithExtendedChars() throws Exception {
public void shouldGetFileFromVCardWithExtendedChars() {
VCard johnDoe = new VCard("John Doe")
.setName("Björkelundsvägen")
.setEmail("john.doe@example.org")
@@ -47,36 +51,44 @@ public void shouldGetFileFromVCardWithExtendedChars() throws Exception {
.setPhoneNumber("1234")
.setWebsite("www.Björkelundsvägen.org");
File file = QRCode.from(johnDoe).file();
Assert.assertNotNull(file);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetBitmapFileFromText() throws Exception {
public void shouldGetBitmapFileFromText() {
File file = QRCode.from("www.example.org").to(ImageType.BMP).file();
Assert.assertNotNull(file);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetFileFromTextWithDefaults() throws Exception {
public void shouldGetFileFromTextWithDefaults() {
File file = QRCode.from("Hello World").file();
Assert.assertNotNull(file);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetFileWithNameFromTextWithDefaults() throws Exception {
public void shouldGetFileWithNameFromTextWithDefaults() {
File file = QRCode.from("Hello World").file("Hello World");
Assert.assertNotNull(file);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
Assert.assertTrue(file.getName().startsWith("Hello World"));
}
@Test
public void shouldGetSTREAMFromTextWithDefaults() throws Exception {
public void shouldGetSTREAMFromTextWithDefaults() {
ByteArrayOutputStream stream = QRCode.from("Hello World").stream();
Assert.assertNotNull(stream);
}
@Test
public void shouldHandleLargeString() throws Exception {
public void shouldHandleLargeString() {
int length = 2950;
char[] chars = new char[length];
for (int i = 0; i < length; i++) {
@@ -86,24 +98,30 @@ public void shouldHandleLargeString() throws Exception {
Assert.assertEquals(length, text.length());
File file = QRCode.from(text).to(ImageType.PNG).file();
Assert.assertNotNull(file);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetFileFromTextWithImageTypeOverrides() throws Exception {
public void shouldGetFileFromTextWithImageTypeOverrides() {
File jpg = QRCode.from("Hello World").to(ImageType.JPG).file();
Assert.assertNotNull(jpg);
File gif = QRCode.from("Hello World").to(ImageType.GIF).file();
Assert.assertNotNull(gif);
assertThat(gif).exists();
assertThat(gif).canRead();
assertThat(gif.length()).isGreaterThan(0);
}
@Test
public void shouldGetFileWithNameFromTextWithImageTypeOverrides() throws Exception {
public void shouldGetFileWithNameFromTextWithImageTypeOverrides() {
File jpg = QRCode.from("Hello World").to(ImageType.JPG).file("Hello World");
Assert.assertNotNull(jpg);
Assert.assertTrue(jpg.getName().startsWith("Hello World"));
File gif = QRCode.from("Hello World").to(ImageType.GIF).file("Hello World");
Assert.assertNotNull(gif);
assertThat(gif).exists();
assertThat(gif).canRead();
assertThat(gif.length()).isGreaterThan(0);
Assert.assertTrue(gif.getName().startsWith("Hello World"));
}
@@ -115,7 +133,7 @@ public void shouldGetStreamFromText() throws Exception {
long lengthBefore = tempFile.length();
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
stream.writeTo(fileOutputStream);
Assert.assertTrue(lengthBefore < tempFile.length());
assertThat(tempFile.length()).isGreaterThan(lengthBefore);
}
@Test
@@ -128,32 +146,36 @@ public void shouldWriteToSuppliedStream() throws Exception {
long lengthBefore = tempFile.length();
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
stream.writeTo(fileOutputStream);
Assert.assertTrue(lengthBefore < tempFile.length());
assertThat(tempFile.length()).isGreaterThan(lengthBefore);
}
@Test
public void shouldBeAbleToOverrideDimensionsToFile() throws Exception {
public void shouldBeAbleToOverrideDimensionsToFile() {
long defaultSize = QRCode.from("Hello World").to(ImageType.PNG).file().length();
long defaultSize2 = QRCode.from("Hello World").to(ImageType.PNG).file().length();
File file = QRCode.from("Hello World").to(ImageType.PNG).withSize(250, 250).file();
Assert.assertNotNull(file);
Assert.assertTrue(defaultSize == defaultSize2);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
Assert.assertEquals(defaultSize, defaultSize2);
Assert.assertTrue(defaultSize < file.length());
}
@Test
public void shouldBeAbleToOverrideDimensionsToFileWithName() throws Exception {
public void shouldBeAbleToOverrideDimensionsToFileWithName() {
long defaultSize = QRCode.from("Hello World").to(ImageType.PNG).file("Hello World").length();
long defaultSize2 = QRCode.from("Hello World").to(ImageType.PNG).file("Hello World").length();
File file = QRCode.from("Hello World").to(ImageType.PNG).withSize(250, 250).file("Hello World");
Assert.assertNotNull(file);
Assert.assertTrue(defaultSize == defaultSize2);
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
Assert.assertEquals(defaultSize, defaultSize2);
Assert.assertTrue(defaultSize < file.length());
Assert.assertTrue(file.getName().startsWith("Hello World"));
}
@Test
public void shouldBeAbleToSupplyEncodingHint() throws Exception {
public void shouldBeAbleToSupplyEncodingHint() {
String expected = "UTF-8";
final Object[] capture = new Object[1];
try {
@@ -166,7 +188,7 @@ public void shouldBeAbleToSupplyEncodingHint() throws Exception {
}
@Test
public void shouldBeAbleToSupplyErrorCorrectionHint() throws Exception {
public void shouldBeAbleToSupplyErrorCorrectionHint() {
ErrorCorrectionLevel expected = ErrorCorrectionLevel.L;
final Object[] capture = new Object[1];
try {
@@ -199,7 +221,28 @@ public void shouldColorOutput() throws IOException {
File file = QRCode.from("Hello World").withColor(0xFFFF0000, 0xFFFFFFAA).file();
File tempFile = File.createTempFile("qr_", ".png");
Files.copy(file.toPath(), new FileOutputStream(tempFile));
System.out.println(tempFile.getAbsoluteFile());
}
@Test
public void shouldGetSvgFromText() {
File file = QRCode.from("www.example.org").svg();
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetSvgWithSizeFromText() {
File file = QRCode.from("www.example.com").withSize(250, 250).svg();
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@Test
public void shouldGetSvgWithSizeAndColorFromText() {
File file = QRCode.from("www.example.com").withSize(250, 250).withColor(30, 90).svg();
assertThat(file).exists();
assertThat(file).canRead();
assertThat(file.length()).isGreaterThan(0);
}
@SuppressWarnings("unchecked")
View
20 pom.xml
@@ -45,6 +45,7 @@
<properties>
<zxing.version>3.3.0</zxing.version>
<batik.version>1.10</batik.version>
<junit.version>4.8.2</junit.version>
<robolectric.version>2.2</robolectric.version>
<fest-android.version>1.0.7</fest-android.version>
@@ -53,6 +54,8 @@
<maven-compiler-plugin.target>1.7</maven-compiler-plugin.target>
<maven-compiler-plugin.version>2.3.2</maven-compiler-plugin.version>
<maven-checkstyle-plugin.version>2.12.1</maven-checkstyle-plugin.version>
<maven-javadoc-plugin.version>3.0.1</maven-javadoc-plugin.version>
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
<nexus-staging-maven-plugin.version>1.6.4</nexus-staging-maven-plugin.version>
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
</properties>
@@ -133,6 +136,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven-source-plugin.version}</version>
<executions>
<execution>
<goals>
@@ -156,6 +160,22 @@
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svggen</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-dom</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>

0 comments on commit a630af3

Please sign in to comment.