EOD
This commit is contained in:
parent
c530a55f2f
commit
c7bfdd4fc1
@ -12,25 +12,36 @@ public class Main {
|
|||||||
Location.loadLocations();
|
Location.loadLocations();
|
||||||
|
|
||||||
port(8080);
|
port(8080);
|
||||||
get("/heartbeat", (req, res) -> {
|
path("/backend", () -> {
|
||||||
res.status(200);
|
before("/*");
|
||||||
res.type("application/json");
|
|
||||||
res.header("Access-Control-Allow-Origin", "*");
|
|
||||||
return "{ \"up\":true }";
|
|
||||||
});
|
|
||||||
|
|
||||||
get("/data/locations", (req, res) -> {
|
get("/heartbeat", (req, res) -> {
|
||||||
res.status(200);
|
res.status(200);
|
||||||
res.type("application/json");
|
res.type("application/json");
|
||||||
res.header("Access-Control-Allow-Origin", "*");
|
res.header("Access-Control-Allow-Origin", "*");
|
||||||
return new FileInputStream("locations.json");
|
return "{ \"up\":true }";
|
||||||
});
|
});
|
||||||
|
|
||||||
post("/", (req, res) -> {
|
get("/data/locations", (req, res) -> {
|
||||||
res.type("image/png");
|
res.status(200);
|
||||||
res.header("Access-Control-Allow-Origin", "*");
|
res.type("application/json");
|
||||||
JsonObject data = new Gson().fromJson(req.body(), JsonObject.class);
|
res.header("Access-Control-Allow-Origin", "*");
|
||||||
return new VCard(data).toByteArray();
|
return new FileInputStream("locations.json");
|
||||||
|
});
|
||||||
|
|
||||||
|
post("/generate", (req, res) -> {
|
||||||
|
res.type("image/png");
|
||||||
|
res.header("Access-Control-Allow-Origin", "*");
|
||||||
|
JsonObject data = new Gson().fromJson(req.body(), JsonObject.class);
|
||||||
|
return new VCard(data).toByteArray();
|
||||||
|
});
|
||||||
|
|
||||||
|
post("/edit", (req, res) -> {
|
||||||
|
res.status(200);
|
||||||
|
res.type("application/json");
|
||||||
|
res.header("Access-Control-Allow-Origin", "*");
|
||||||
|
return VCard.getDataFromVCard(req.bodyAsBytes());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
package tech.nevets.vcardgen;
|
package tech.nevets.vcardgen;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.*;
|
||||||
|
import javax.imageio.metadata.IIOMetadata;
|
||||||
|
import javax.imageio.metadata.IIOMetadataNode;
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
import javax.imageio.stream.ImageOutputStream;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class VCard {
|
public class VCard {
|
||||||
private static final Color WHITE = new Color(255, 255, 255);
|
private static final Color WHITE = new Color(255, 255, 255);
|
||||||
@ -20,7 +28,11 @@ public class VCard {
|
|||||||
private static final Font ARIAL40I = new Font("Arial", Font.ITALIC, 40);
|
private static final Font ARIAL40I = new Font("Arial", Font.ITALIC, 40);
|
||||||
private static final Font ARIAL38I = new Font("Arial", Font.ITALIC, 38);
|
private static final Font ARIAL38I = new Font("Arial", Font.ITALIC, 38);
|
||||||
|
|
||||||
|
private static final String[] KEYS = {"Name", "Title", "Email", "Location", "Address", "SchoolNumber", "Extension", "DirectNumber", "CellNumber"};
|
||||||
|
|
||||||
|
private BufferedImage rawImage = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
|
||||||
private BufferedImage workingImage = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
|
private BufferedImage workingImage = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
private IIOImage finalImage;
|
||||||
|
|
||||||
private final String[] data = new String[9];
|
private final String[] data = new String[9];
|
||||||
private final boolean[] flags = new boolean[3]; // 0 - Long Address, 1 - Has Direct Number, 2 - Has Cell Phone
|
private final boolean[] flags = new boolean[3]; // 0 - Long Address, 1 - Has Direct Number, 2 - Has Cell Phone
|
||||||
@ -34,7 +46,7 @@ public class VCard {
|
|||||||
Location location = Location.getLocation(json.get("locationId").getAsString());
|
Location location = Location.getLocation(json.get("locationId").getAsString());
|
||||||
this.data[3] = location.getName(); //locationName
|
this.data[3] = location.getName(); //locationName
|
||||||
this.data[4] = location.getAddress(); //address
|
this.data[4] = location.getAddress(); //address
|
||||||
this.data[5] = location.getName(); //schoolNumber
|
this.data[5] = location.getNumber(); //schoolNumber
|
||||||
background = location.getBackground();
|
background = location.getBackground();
|
||||||
this.data[6] = json.get("extension").getAsString(); //extension
|
this.data[6] = json.get("extension").getAsString(); //extension
|
||||||
this.data[7] = json.get("directNumber").getAsString(); //directNumber
|
this.data[7] = json.get("directNumber").getAsString(); //directNumber
|
||||||
@ -44,6 +56,13 @@ public class VCard {
|
|||||||
size = json.get("size").getAsInt();
|
size = json.get("size").getAsInt();
|
||||||
|
|
||||||
renderImage();
|
renderImage();
|
||||||
|
resizeImage();
|
||||||
|
try {
|
||||||
|
addMetadata();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error adding metadata");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public VCard(String name, String title, String email, String locationId, String extension, String directNumber, String cellNumber, int size) {
|
public VCard(String name, String title, String email, String locationId, String extension, String directNumber, String cellNumber, int size) {
|
||||||
@ -63,6 +82,13 @@ public class VCard {
|
|||||||
this.size = size;
|
this.size = size;
|
||||||
|
|
||||||
renderImage();
|
renderImage();
|
||||||
|
resizeImage();
|
||||||
|
try {
|
||||||
|
addMetadata();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error adding metadata");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderImage() {
|
private void renderImage() {
|
||||||
@ -71,15 +97,12 @@ public class VCard {
|
|||||||
|
|
||||||
g.drawImage(background, 0, 0, null);
|
g.drawImage(background, 0, 0, null);
|
||||||
|
|
||||||
FontMetrics fm = g.getFontMetrics(ARIAL65);
|
|
||||||
|
|
||||||
g.setColor(WHITE);
|
g.setColor(WHITE);
|
||||||
if (fm.stringWidth(data[0]) <= 969) g.setFont(ARIAL65);
|
if (fitsDimensions(data[0], ARIAL65, 969)) g.setFont(ARIAL65);
|
||||||
else g.setFont(ARIAL55);
|
else g.setFont(ARIAL55);
|
||||||
g.drawString(data[0], 85, 112);
|
g.drawString(data[0], 85, 112);
|
||||||
|
|
||||||
fm = g.getFontMetrics(ARIAL45I);
|
if (fitsDimensions(data[1], ARIAL45I, 970)) g.setFont(ARIAL45I);
|
||||||
if (fm.stringWidth(data[1]) <= 970) g.setFont(ARIAL45I);
|
|
||||||
else g.setFont(ARIAL40I);
|
else g.setFont(ARIAL40I);
|
||||||
g.drawString(data[1], 89, 176);
|
g.drawString(data[1], 89, 176);
|
||||||
|
|
||||||
@ -88,9 +111,7 @@ public class VCard {
|
|||||||
doubleNumOffset = 40;
|
doubleNumOffset = 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
int longAddrOffset = 0;
|
int longAddrOffset = fitsDimensions(data[4], ARIAL38I, 694) ? 0 : 40;
|
||||||
fm = g.getFontMetrics(ARIAL38I);
|
|
||||||
if (fm.stringWidth(data[4]) > 694) longAddrOffset = 40;
|
|
||||||
|
|
||||||
g.setFont(ARIAL45);
|
g.setFont(ARIAL45);
|
||||||
g.drawString(data[2], 62, 380 - doubleNumOffset - longAddrOffset);
|
g.drawString(data[2], 62, 380 - doubleNumOffset - longAddrOffset);
|
||||||
@ -99,14 +120,14 @@ public class VCard {
|
|||||||
g.setFont(ARIAL44I);
|
g.setFont(ARIAL44I);
|
||||||
g.drawString(data[3], 59, 447 - doubleNumOffset - longAddrOffset);
|
g.drawString(data[3], 59, 447 - doubleNumOffset - longAddrOffset);
|
||||||
|
|
||||||
if (fm.stringWidth(data[4]) >= 694) {
|
if (!fitsDimensions(data[4], ARIAL38I, 694)) {
|
||||||
StringBuilder addrLineOne = new StringBuilder();
|
StringBuilder addrLineOne = new StringBuilder();
|
||||||
StringBuilder addrLineTwo = new StringBuilder();
|
StringBuilder addrLineTwo = new StringBuilder();
|
||||||
|
|
||||||
String[] splitAddr = data[4].split(",");
|
String[] splitAddr = data[4].split(",");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int width = 0; width < 694; i++) {
|
for (int width = 0; width < 694; i++) {
|
||||||
int splitSize = fm.stringWidth(splitAddr[i]);
|
int splitSize = g.getFontMetrics().stringWidth(splitAddr[i]);
|
||||||
if ((width + splitSize) < 694) {
|
if ((width + splitSize) < 694) {
|
||||||
width += splitSize;
|
width += splitSize;
|
||||||
addrLineOne.append(splitAddr[i]);
|
addrLineOne.append(splitAddr[i]);
|
||||||
@ -132,15 +153,13 @@ public class VCard {
|
|||||||
|
|
||||||
String number;
|
String number;
|
||||||
int numY = flags[2] ? 496 : 540;
|
int numY = flags[2] ? 496 : 540;
|
||||||
|
|
||||||
if (!flags[1]) number = "W: " + data[5] + " x" + data[6];
|
if (!flags[1]) number = "W: " + data[5] + " x" + data[6];
|
||||||
else number = "W: " + data[7];
|
else number = "W: " + data[7];
|
||||||
|
|
||||||
g.drawString(number, 59, numY);
|
g.drawString(number, 59, numY);
|
||||||
|
|
||||||
if (flags[2]) g.drawString("C: " + data[8], 59, 540);
|
if (flags[2]) g.drawString("C: " + data[8], 59, 540);
|
||||||
|
|
||||||
g.dispose();
|
g.dispose();
|
||||||
|
rawImage = workingImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resizeImage() {
|
public void resizeImage() {
|
||||||
@ -151,7 +170,7 @@ public class VCard {
|
|||||||
BufferedImage resizedImage;
|
BufferedImage resizedImage;
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 0 -> resizedImage = resizeImage(300, 167, false);
|
case 0 -> resizedImage = resizeImage(300, 167, false);
|
||||||
case 1 -> resizedImage = workingImage;
|
case 1 -> resizedImage = rawImage;
|
||||||
default -> resizedImage = background;
|
default -> resizedImage = background;
|
||||||
}
|
}
|
||||||
workingImage = resizedImage;
|
workingImage = resizedImage;
|
||||||
@ -162,43 +181,63 @@ public class VCard {
|
|||||||
Graphics2D g = resizedImage.createGraphics();
|
Graphics2D g = resizedImage.createGraphics();
|
||||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||||
if (antiAlias) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
if (antiAlias) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
g.drawImage(workingImage, 0, 0, width, height, null);
|
g.drawImage(rawImage, 0, 0, width, height, null);
|
||||||
g.dispose();
|
g.dispose();
|
||||||
return resizedImage;
|
return resizedImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toByteArray() {
|
public void addMetadata() throws IOException {
|
||||||
ByteArrayOutputStream baos;
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try {
|
ImageIO.write(workingImage, "png", baos);
|
||||||
baos = new ByteArrayOutputStream();
|
|
||||||
ImageIO.write(workingImage, "png", baos);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ImageReader reader = ImageIO.getImageReadersByMIMEType("image/png").next();
|
||||||
|
reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(baos.toByteArray())));
|
||||||
|
finalImage = reader.readAll(0, null);
|
||||||
|
|
||||||
|
IIOMetadataNode text = new IIOMetadataNode("tEXt");
|
||||||
|
for (int i = 0; i < KEYS.length; i++) {
|
||||||
|
IIOMetadataNode textEntry = new IIOMetadataNode("tEXtEntry");
|
||||||
|
textEntry.setAttribute("keyword", KEYS[i]);
|
||||||
|
textEntry.setAttribute("value", data[i]);
|
||||||
|
text.appendChild(textEntry);
|
||||||
|
}
|
||||||
|
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_png_1.0");
|
||||||
|
root.appendChild(text);
|
||||||
|
|
||||||
|
finalImage.getMetadata().mergeTree("javax_imageio_png_1.0", root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toByteArray() throws IOException {
|
||||||
|
ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/png").next();
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
|
||||||
|
writer.setOutput(ios);
|
||||||
|
writer.write(finalImage);
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean[] bitFlags(int bits) {
|
private static final Canvas C = new Canvas();
|
||||||
boolean[] flags = new boolean[bits];
|
|
||||||
for (int i = 0; i < flags.length; i++) {
|
|
||||||
flags[i] = ((bits) & (1 << ((flags.length - i) - 1))) != 0;
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int bitFlagsFromFlags(boolean[] flags) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (boolean b : flags) {
|
|
||||||
sb.append(b ? "1" : "0");
|
|
||||||
}
|
|
||||||
return Integer.parseInt(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean fitsDimensions(String text, Font font, int maxLength) {
|
private static boolean fitsDimensions(String text, Font font, int maxLength) {
|
||||||
Canvas c = new Canvas();
|
return C.getFontMetrics(font).stringWidth(text) < maxLength;
|
||||||
FontMetrics fm = c.getFontMetrics(font);
|
}
|
||||||
return fm.stringWidth(text) < maxLength;
|
|
||||||
|
public static String getDataFromVCard(byte[] rawImage) throws IOException {
|
||||||
|
ImageReader reader = ImageIO.getImageReadersByMIMEType("image/png").next();
|
||||||
|
reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(rawImage)));
|
||||||
|
|
||||||
|
IIOMetadata metadata = reader.getImageMetadata(0);
|
||||||
|
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree("javax_imageio_png_1.0");
|
||||||
|
IIOMetadataNode text = (IIOMetadataNode) root.getElementsByTagName("tEXt").item(0);
|
||||||
|
int numTextEntries = text.getLength();
|
||||||
|
|
||||||
|
Map<String, String> keyValueMap = new HashMap<>();
|
||||||
|
for (int i = 0; i < numTextEntries; i++) {
|
||||||
|
IIOMetadataNode textEntry = (IIOMetadataNode) text.item(i);
|
||||||
|
String key = textEntry.getAttribute("keyword");
|
||||||
|
String value = textEntry.getAttribute("value");
|
||||||
|
keyValueMap.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Gson().toJson(keyValueMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user