Websocket works!

This commit is contained in:
Steven Tracey 2023-06-06 16:12:12 -04:00
parent 26d4857221
commit d371cf4a89
4 changed files with 125 additions and 114 deletions

View File

@ -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 <br>0: Both double number and long address<br>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<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");
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);

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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;
}
}