diff --git a/src/main/java/tech/nevets/vcardgen/Card.java b/src/main/java/tech/nevets/vcardgen/Card.java
index 6aa8eac..abdb3bb 100644
--- a/src/main/java/tech/nevets/vcardgen/Card.java
+++ b/src/main/java/tech/nevets/vcardgen/Card.java
@@ -17,7 +17,7 @@ public class Card {
// ---------------- COLORS ---------------- //
private static final Color WHITE = new Color(255, 255, 255);
- private static final Color GREEN = new Color(101, 142, 61);
+ private static final Color GREEN = new Color(101, 141, 27);
// ---------------- FONTS ---------------- //
private static final Font ARIAL65 = new Font("Arial", Font.PLAIN, 65);
@@ -30,11 +30,11 @@ public class Card {
// ---------------- LAYERS ---------------- //
private BufferedImage background;
- private BufferedImage nameLayer = new BufferedImage(975, 90, BufferedImage.TYPE_INT_ARGB);
- private BufferedImage titleLayer = new BufferedImage(975, 55, BufferedImage.TYPE_INT_ARGB);
- private BufferedImage emailLayer = new BufferedImage(1000, 55, BufferedImage.TYPE_INT_ARGB);
- private BufferedImage locationLayer = new BufferedImage(700, 134, BufferedImage.TYPE_INT_ARGB);
- private BufferedImage phoneNumbersLayer = new BufferedImage(700, 90, BufferedImage.TYPE_INT_ARGB);
+ private BufferedImage nameLayer = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
+ private BufferedImage titleLayer = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
+ private BufferedImage emailLayer = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
+ private BufferedImage locationLayer = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
+ private BufferedImage phoneNumbersLayer = new BufferedImage(1080, 602, BufferedImage.TYPE_INT_ARGB);
// ---------------- Working Images ---------------- //
private Graphics2D graphics;
@@ -43,7 +43,7 @@ public class Card {
private IIOImage finalImage;
// ---------------- DATA ---------------- //
- public String id;
+ public final String id;
private String name;
private String title;
private String email;
@@ -147,40 +147,37 @@ public class Card {
return background;
}
- private BufferedImage renderLayer(BufferedImage layer, String content, Color textColor, Font font) {
- return renderLayer(layer, content, textColor, font, 0, 0);
- }
-
private BufferedImage renderLayer(BufferedImage layer, String content, Color textColor, Font font, int x, int y) {
graphics = layer.createGraphics();
setAntiAlias(graphics);
graphics.setColor(textColor);
+ graphics.setFont(font);
graphics.drawString(content, x, y);
graphics.dispose();
return layer;
}
- private BufferedImage renderResizableLayer(BufferedImage layer, String content, Color textColor, int maxLength, Font defaultFont, Font smallFont) {
+ private BufferedImage renderResizableLayer(BufferedImage layer, String content, Color textColor, int maxLength, Font defaultFont, Font smallFont, int x, int y) {
graphics = layer.createGraphics();
setAntiAlias(graphics);
graphics.setColor(textColor);
if (fitsDimensions(content, defaultFont, maxLength)) graphics.setFont(defaultFont);
else graphics.setFont(smallFont);
- graphics.drawString(content, 0, 0);
+ graphics.drawString(content, x, y);
graphics.dispose();
return layer;
}
public BufferedImage renderNameLayer() {
- return renderResizableLayer(nameLayer, name, WHITE, 970, ARIAL65, ARIAL55);
+ return renderResizableLayer(nameLayer, name, WHITE, 970, ARIAL65, ARIAL55, 85, 112);
}
public BufferedImage renderTitleLayer() {
- return renderResizableLayer(titleLayer, title, WHITE, 970, ARIAL45I, ARIAL40I);
+ return renderResizableLayer(titleLayer, title, WHITE, 970, ARIAL45I, ARIAL40I, 89, 176);
}
public BufferedImage renderEmailLayer() {
- return renderLayer(emailLayer, email, WHITE, ARIAL45);
+ return renderLayer(emailLayer, email, WHITE, ARIAL45, 62, (380 - getOffsets(0)));
}
public BufferedImage renderLocationLayer() {
@@ -205,71 +202,54 @@ public class Card {
sb.insert(newLineIndex - 2, "\n");
sb.deleteCharAt(sb.length() - 1);
}
- renderLayer(locationLayer, location.getName(), GREEN, ARIAL44I);
- return renderLayer(locationLayer, sb.toString(), GREEN, ARIAL38I, 0, 44);
+ renderLayer(locationLayer, location.getName(), GREEN, ARIAL44I, 59, (447 - getOffsets(0)));
+ return renderLayer(locationLayer, sb.toString(), GREEN, ARIAL38I, 59, (491 - getOffsets(0)));
}
public BufferedImage renderPhoneNumbersLayer() {
- return null;
+ if (hasDirectNumber) {
+ renderLayer(phoneNumbersLayer, ("W: " + directNumber), GREEN, ARIAL38I, 59, (540 - getOffsets(1)));
+ } else {
+ renderLayer(phoneNumbersLayer, ("W: " + location.getNumber() + " x" + extension), GREEN, ARIAL38I, 59, (540 - getOffsets(1)));
+ }
+ if (hasCellNumber) {
+ renderLayer(phoneNumbersLayer, ("C: " + cellNumber), GREEN, ARIAL38I, 59, 540);
+ }
+ return phoneNumbersLayer;
}
- private void renderImage() {
+ public void renderImage() {
graphics = rawImage.createGraphics();
setAntiAlias(graphics);
graphics.drawImage(background, 0, 0, null);
- graphics.drawImage(renderNameLayer(), 85, 112, null);
- graphics.drawImage(renderTitleLayer(), 89, 176, null);
-
- int doubleNumOffset = hasDirectNumber ? 40 : 0;
- int longAddrOffset = fitsDimensions(location.getAddress(), ARIAL38I, 700) ? 0 : 40;
-
- graphics.drawImage(renderEmailLayer(), 62, (380 - doubleNumOffset - longAddrOffset), null);
-
- graphics.setColor(GREEN);
- graphics.setFont(ARIAL44I);
- graphics.drawString(location.getName(), 59, 447 - doubleNumOffset - longAddrOffset);
-
- if (!fitsDimensions(location.getAddress(), ARIAL38I, 694)) {
- StringBuilder addrLineOne = new StringBuilder();
- StringBuilder addrLineTwo = new StringBuilder();
-
- String[] splitAddr = location.getAddress().split(",");
- int i = 0;
- for (int width = 0; width < 694; i++) {
- int splitSize = graphics.getFontMetrics().stringWidth(splitAddr[i]);
- if ((width + splitSize) < 694) {
- width += splitSize;
- addrLineOne.append(splitAddr[i]);
- addrLineOne.append(",");
- } else {
- addrLineOne.deleteCharAt(addrLineOne.length() - 1);
- break;
- }
- }
-
- for (; i < splitAddr.length; i++) {
- addrLineTwo.append(splitAddr[i]);
- addrLineTwo.append(",");
- }
- addrLineTwo.deleteCharAt(addrLineTwo.length() - 1);
-
- graphics.setFont(ARIAL38I);
- graphics.drawString(addrLineOne.toString().trim(), 59, 491 - doubleNumOffset - longAddrOffset);
- graphics.drawString(addrLineTwo.toString().trim(), 59, 491 - doubleNumOffset);
- } else {
- graphics.drawString(location.getAddress(), 59, 491 - doubleNumOffset);
- }
-
- String number;
- int numY = hasDirectNumber ? 496 : 540;
- if (!hasDirectNumber) number = "W: " + location.getNumber() + " x" + extension;
- else number = "W: " + directNumber;
- graphics.drawString(number, 59, numY);
- if (hasCellNumber) graphics.drawString("C: " + cellNumber, 59, 540);
+ graphics.drawImage(renderNameLayer(), 0, 0, null);
+ graphics.drawImage(renderTitleLayer(), 0, 0, null);
+ graphics.drawImage(renderEmailLayer(), 0, 0, null);
+ graphics.drawImage(renderLocationLayer(), 0, 0, null);
+ graphics.drawImage(renderPhoneNumbersLayer(), 0, 0, null);
graphics.dispose();
- rawImage = workingImage;
+ resizeImage();
+ }
+
+ /**
+ * Gets offsets for necessary layers
+ * @param type
0: Both double number and long address
1: Only double number
+ * @return Negative integer value for pixel offset
+ */
+ private int getOffsets(int type) {
+ int totalOffset = 0;
+ int doubleNumberOffset = hasDirectNumber ? 40 : 0;
+ int longAddrOffset = fitsDimensions(location.getAddress(), ARIAL38I, 700) ? 0 : 40;
+ switch (type) {
+ case 0 -> {
+ totalOffset -= doubleNumberOffset;
+ totalOffset -= longAddrOffset;
+ }
+ case 1 -> totalOffset -= doubleNumberOffset;
+ }
+ return totalOffset;
}
public void resizeImage() {
@@ -305,12 +285,9 @@ public class Card {
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 textEntry = new IIOMetadataNode("tEXtEntry");
+ textEntry.setAttribute("contents", toMetaString(this));
+ text.appendChild(textEntry);
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_png_1.0");
root.appendChild(text);
@@ -318,6 +295,7 @@ public class Card {
}
public byte[] toByteArray() throws IOException {
+ addMetadata();
ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/png").next();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
@@ -338,6 +316,16 @@ public class Card {
return C.getFontMetrics(font).stringWidth(text);
}
+ public static String toMetaString(Card card) {
+ return "name=" + card.name + ";" +
+ "title=" + card.title + ";" +
+ "email=" + card.email + ";" +
+ "locationId=" + card.location.getId() + ";" +
+ "extension=" + card.extension + ";" +
+ "directNumber=" + card.directNumber + ";" +
+ "cellNumber=" + card.cellNumber + ";";
+ }
+
public static String getDataFromVCard(InputStream rawImage) throws IOException {
ImageReader reader = ImageIO.getImageReadersByMIMEType("image/png").next();
reader.setInput(ImageIO.createImageInputStream(rawImage));
@@ -348,20 +336,13 @@ public class Card {
if (text == null) {
return "$null";
}
- int numTextEntries = text.getLength();
Map 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");
- if (key.equals("Address") || key.equals("SchoolNumber")) {
- continue;
- }
- if (key.equals("Location")) {
- value = Location.getLocationId(value);
- }
- keyValueMap.put(key, value);
+ String contents = ((IIOMetadataNode) text.item(0)).getAttribute("contents");
+ String[] contentSplit = contents.split(";");
+ for (String entry : contentSplit) {
+ String[] kvPair = entry.split("=");
+ keyValueMap.put(kvPair[0], kvPair[1]);
}
return new Gson().toJson(keyValueMap);
diff --git a/src/main/java/tech/nevets/vcardgen/GenerateRoute.java b/src/main/java/tech/nevets/vcardgen/GenerateRoute.java
index 81bb579..b1a5fdf 100644
--- a/src/main/java/tech/nevets/vcardgen/GenerateRoute.java
+++ b/src/main/java/tech/nevets/vcardgen/GenerateRoute.java
@@ -20,13 +20,15 @@ public class GenerateRoute implements Route {
res.status(422);
return "Not valid json: " + e.getMessage();
}
+ card = new Card(data);
+ card.renderImage();
res.type("image/png");
res.header("Access-Control-Expose-Headers", "Id");
- card = new Card(data);
+ res.header("Id", card.id);
try {
res.status(200);
- return new Card(data).toByteArray();
+ return card.toByteArray();
} catch (IOException e) {
res.status(500);
return "Error getting image stream: " + e.getMessage();
diff --git a/src/main/java/tech/nevets/vcardgen/LiveGenWebSocket.java b/src/main/java/tech/nevets/vcardgen/LiveGenWebSocket.java
index ed84b64..43785e9 100644
--- a/src/main/java/tech/nevets/vcardgen/LiveGenWebSocket.java
+++ b/src/main/java/tech/nevets/vcardgen/LiveGenWebSocket.java
@@ -19,21 +19,33 @@ public class LiveGenWebSocket {
public void connected(Session session) {}
@OnWebSocketClose
- public void closed(Session session, int statusCode, String reason) {}
+ public void closed(Session session, int statusCode, String reason) {
+ card = null;
+ }
+
+ @OnWebSocketError
+ public void error(Session session, Throwable throwable) {
+ throwable.printStackTrace();
+ }
@OnWebSocketMessage
public void message(Session session, String message) throws IOException {
- String[] splitMsg = message.split(";");
- String messageType = splitMsg[0];
- String messageContent = splitMsg[1];
-
RemoteEndpoint client = session.getRemote();
- switch (messageType) {
- case "start" -> {
+ System.out.println(message);
+ String[] splitMsg = message.split(";");
+ String messageType = splitMsg[0];
+
+ if (splitMsg.length == 1) {
+ if (messageType.equals("start")) {
card = new Card();
client.sendString("success;Card successfully created.");
}
+ return;
+ }
+ String messageContent = splitMsg[1];
+
+ switch (messageType) {
case "continue" -> {
card = Card.CARD_SESSIONS.get(messageContent);
if (card == null) {
@@ -43,32 +55,46 @@ public class LiveGenWebSocket {
client.sendString("success;Card loaded successfully.");
}
}
- case "location" -> {
- card.setLocation(Location.getLocation(messageContent));
+ case "background" -> {
client.sendString("background");
client.sendBytes(byteBufferFromImage(card.getBackground()));
+ }
+ case "location" -> {
+ card.setLocation(Location.getLocation(messageContent));
client.sendString("location");
client.sendBytes(byteBufferFromImage(card.renderLocationLayer()));
}
case "name" -> {
-
+ card.setName(messageContent);
+ client.sendString("name");
+ client.sendBytes(byteBufferFromImage(card.renderNameLayer()));
}
case "title" -> {
-
+ card.setTitle(messageContent);
+ client.sendString("title");
+ client.sendBytes(byteBufferFromImage(card.renderTitleLayer()));
}
case "email" -> {
-
+ card.setEmail(messageContent);
+ client.sendString("email");
+ client.sendBytes(byteBufferFromImage(card.renderEmailLayer()));
}
case "extension" -> {
-
+ card.setExtension(messageContent);
+ client.sendString("extension");
+ client.sendBytes(byteBufferFromImage(card.renderPhoneNumbersLayer()));
}
case "directNumber" -> {
-
+ card.setDirectNumber(messageContent);
+ client.sendString("directNumber");
+ client.sendBytes(byteBufferFromImage(card.renderPhoneNumbersLayer()));
}
case "cellNumber" -> {
-
+ card.setCellNumber(messageContent);
+ client.sendString("cellNumber");
+ client.sendBytes(byteBufferFromImage(card.renderPhoneNumbersLayer()));
}
- default -> session.getRemote().sendString("Unknown Message Type: " + messageType);
+ default -> client.sendString("Unknown Message Type: " + messageType);
}
}
diff --git a/src/main/java/tech/nevets/vcardgen/Location.java b/src/main/java/tech/nevets/vcardgen/Location.java
index c00d641..cb7ab8b 100644
--- a/src/main/java/tech/nevets/vcardgen/Location.java
+++ b/src/main/java/tech/nevets/vcardgen/Location.java
@@ -21,12 +21,12 @@ public class Location {
private final String number;
private transient BufferedImage background;
- public Location(String id, String name, String address, String number) throws IOException {
+ public Location(String id, String name, String address, String number) {
this.id = id;
this.name = name;
this.address = address;
this.number = number;
- background = ImageIO.read(this.getClass().getResourceAsStream("/backgrounds/" + id + ".png"));
+ loadBackground();
}
public String getId() {
@@ -49,10 +49,14 @@ public class Location {
return background;
}
- public void loadBackground() throws IOException {
+ public void loadBackground() {
URL backgroundURL = this.getClass().getResource("/backgrounds/" + id + ".png");
if (backgroundURL == null) backgroundURL = this.getClass().getResource("/backgrounds/default.png");
- background = ImageIO.read(backgroundURL);
+ try {
+ background = ImageIO.read(backgroundURL);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
@Override
@@ -74,13 +78,13 @@ public class Location {
}
}
- public static Location getLocation (String locationId){
+ public static Location getLocation (String locationId) {
for (Location loc : LOCATIONS) {
if (loc.getId().equals(locationId)) {
return loc;
}
}
- return null;
+ return new Location("", "", "", "");
}
public static String getLocationId(String name) {
@@ -91,6 +95,4 @@ public class Location {
}
return null;
}
-
-
}
\ No newline at end of file