EOD
This commit is contained in:
parent
c530a55f2f
commit
c7bfdd4fc1
@ -12,25 +12,36 @@ public class Main {
|
||||
Location.loadLocations();
|
||||
|
||||
port(8080);
|
||||
get("/heartbeat", (req, res) -> {
|
||||
res.status(200);
|
||||
res.type("application/json");
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
return "{ \"up\":true }";
|
||||
});
|
||||
path("/backend", () -> {
|
||||
before("/*");
|
||||
|
||||
get("/data/locations", (req, res) -> {
|
||||
res.status(200);
|
||||
res.type("application/json");
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
return new FileInputStream("locations.json");
|
||||
});
|
||||
get("/heartbeat", (req, res) -> {
|
||||
res.status(200);
|
||||
res.type("application/json");
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
return "{ \"up\":true }";
|
||||
});
|
||||
|
||||
post("/", (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();
|
||||
get("/data/locations", (req, res) -> {
|
||||
res.status(200);
|
||||
res.type("application/json");
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
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;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
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.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class VCard {
|
||||
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 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 IIOImage finalImage;
|
||||
|
||||
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
|
||||
@ -34,7 +46,7 @@ public class VCard {
|
||||
Location location = Location.getLocation(json.get("locationId").getAsString());
|
||||
this.data[3] = location.getName(); //locationName
|
||||
this.data[4] = location.getAddress(); //address
|
||||
this.data[5] = location.getName(); //schoolNumber
|
||||
this.data[5] = location.getNumber(); //schoolNumber
|
||||
background = location.getBackground();
|
||||
this.data[6] = json.get("extension").getAsString(); //extension
|
||||
this.data[7] = json.get("directNumber").getAsString(); //directNumber
|
||||
@ -44,6 +56,13 @@ public class VCard {
|
||||
size = json.get("size").getAsInt();
|
||||
|
||||
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) {
|
||||
@ -63,6 +82,13 @@ public class VCard {
|
||||
this.size = size;
|
||||
|
||||
renderImage();
|
||||
resizeImage();
|
||||
try {
|
||||
addMetadata();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error adding metadata");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void renderImage() {
|
||||
@ -71,15 +97,12 @@ public class VCard {
|
||||
|
||||
g.drawImage(background, 0, 0, null);
|
||||
|
||||
FontMetrics fm = g.getFontMetrics(ARIAL65);
|
||||
|
||||
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);
|
||||
g.drawString(data[0], 85, 112);
|
||||
|
||||
fm = g.getFontMetrics(ARIAL45I);
|
||||
if (fm.stringWidth(data[1]) <= 970) g.setFont(ARIAL45I);
|
||||
if (fitsDimensions(data[1], ARIAL45I, 970)) g.setFont(ARIAL45I);
|
||||
else g.setFont(ARIAL40I);
|
||||
g.drawString(data[1], 89, 176);
|
||||
|
||||
@ -88,9 +111,7 @@ public class VCard {
|
||||
doubleNumOffset = 40;
|
||||
}
|
||||
|
||||
int longAddrOffset = 0;
|
||||
fm = g.getFontMetrics(ARIAL38I);
|
||||
if (fm.stringWidth(data[4]) > 694) longAddrOffset = 40;
|
||||
int longAddrOffset = fitsDimensions(data[4], ARIAL38I, 694) ? 0 : 40;
|
||||
|
||||
g.setFont(ARIAL45);
|
||||
g.drawString(data[2], 62, 380 - doubleNumOffset - longAddrOffset);
|
||||
@ -99,14 +120,14 @@ public class VCard {
|
||||
g.setFont(ARIAL44I);
|
||||
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 addrLineTwo = new StringBuilder();
|
||||
|
||||
String[] splitAddr = data[4].split(",");
|
||||
int i = 0;
|
||||
for (int width = 0; width < 694; i++) {
|
||||
int splitSize = fm.stringWidth(splitAddr[i]);
|
||||
int splitSize = g.getFontMetrics().stringWidth(splitAddr[i]);
|
||||
if ((width + splitSize) < 694) {
|
||||
width += splitSize;
|
||||
addrLineOne.append(splitAddr[i]);
|
||||
@ -132,15 +153,13 @@ public class VCard {
|
||||
|
||||
String number;
|
||||
int numY = flags[2] ? 496 : 540;
|
||||
|
||||
if (!flags[1]) number = "W: " + data[5] + " x" + data[6];
|
||||
else number = "W: " + data[7];
|
||||
|
||||
g.drawString(number, 59, numY);
|
||||
|
||||
if (flags[2]) g.drawString("C: " + data[8], 59, 540);
|
||||
|
||||
g.dispose();
|
||||
rawImage = workingImage;
|
||||
}
|
||||
|
||||
public void resizeImage() {
|
||||
@ -151,7 +170,7 @@ public class VCard {
|
||||
BufferedImage resizedImage;
|
||||
switch (size) {
|
||||
case 0 -> resizedImage = resizeImage(300, 167, false);
|
||||
case 1 -> resizedImage = workingImage;
|
||||
case 1 -> resizedImage = rawImage;
|
||||
default -> resizedImage = background;
|
||||
}
|
||||
workingImage = resizedImage;
|
||||
@ -162,43 +181,63 @@ public class VCard {
|
||||
Graphics2D g = resizedImage.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
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();
|
||||
return resizedImage;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
ByteArrayOutputStream baos;
|
||||
try {
|
||||
baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(workingImage, "png", baos);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return new byte[0];
|
||||
}
|
||||
public void addMetadata() throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(workingImage, "png", baos);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private boolean[] bitFlags(int bits) {
|
||||
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 final Canvas C = new Canvas();
|
||||
private static boolean fitsDimensions(String text, Font font, int maxLength) {
|
||||
Canvas c = new Canvas();
|
||||
FontMetrics fm = c.getFontMetrics(font);
|
||||
return fm.stringWidth(text) < maxLength;
|
||||
return C.getFontMetrics(font).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