From 1030aa983b68503851df746db2ab61acaa0c1579 Mon Sep 17 00:00:00 2001 From: Sophie Strausberg Date: Sun, 17 Nov 2024 17:48:59 -0500 Subject: [PATCH] fix enums and add image processor --- pom.xml | 10 ++ .../com/appdev/allin/DataInitializer.java | 38 ++--- .../contract/BasketballContractGenerator.java | 2 +- .../java/com/appdev/allin/contract/Event.java | 22 +-- .../appdev/allin/contract/OpposingTeam.java | 44 +++--- .../com/appdev/allin/contract/Rarity.java | 16 +-- .../com/appdev/allin/player/Position.java | 6 +- .../appdev/allin/playerData/PlayerData.java | 22 +-- .../playerData/util/PopulatePlayerData.java | 14 +- .../appdev/allin/utils/ImageProcessor.java | 132 +++++++++++++++++- .../appdev/allin/AllInApplicationTests.java | 4 +- .../appdev/allin/ContractGeneratorTest.java | 4 +- 12 files changed, 227 insertions(+), 87 deletions(-) diff --git a/pom.xml b/pom.xml index 50e774e..2398654 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,16 @@ 17 + + org.imgscalr + imgscalr-lib + 4.2 + + + com.drewnoakes + metadata-extractor + 2.18.0 + org.springframework.boot spring-boot-starter-web diff --git a/src/main/java/com/appdev/allin/DataInitializer.java b/src/main/java/com/appdev/allin/DataInitializer.java index 0d8a8cd..68fe327 100644 --- a/src/main/java/com/appdev/allin/DataInitializer.java +++ b/src/main/java/com/appdev/allin/DataInitializer.java @@ -35,7 +35,7 @@ private void populatePlayers() { new Player( "Chris", "Manon", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 30, "6'5", 209, @@ -46,7 +46,7 @@ private void populatePlayers() { new Player( "Nazir", "Williams", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 1, "6'3", 180, @@ -57,7 +57,7 @@ private void populatePlayers() { new Player( "Isaiah", "Gray", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 13, "6'3", 219, @@ -68,7 +68,7 @@ private void populatePlayers() { new Player( "Guy", "Ragland Jr.", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 21, "6'8", 246, @@ -79,7 +79,7 @@ private void populatePlayers() { new Player( "Sean", "Hansen", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 20, "6'9", 246, @@ -90,7 +90,7 @@ private void populatePlayers() { new Player( "Cooper", "Noard", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 31, "6'2", 190, @@ -101,7 +101,7 @@ private void populatePlayers() { new Player( "AK", "Okereke", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 12, "6'7", 235, @@ -112,7 +112,7 @@ private void populatePlayers() { new Player( "Keller", "Boothby", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 15, "6'7", 223, @@ -123,7 +123,7 @@ private void populatePlayers() { new Player( "Ian", "Imegwu", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 2, "6'9", 226, @@ -134,7 +134,7 @@ private void populatePlayers() { new Player( "Jake", "Fiegen", - new Position[] {Position.Guard}, + new Position[] {Position.FORWARD}, 22, "6'4", 205, @@ -145,7 +145,7 @@ private void populatePlayers() { new Player( "Jacob", "Beccles", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 5, "6'3", 178, @@ -156,7 +156,7 @@ private void populatePlayers() { new Player( "Max", "Watson", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 25, "6'4", 195, @@ -167,7 +167,7 @@ private void populatePlayers() { new Player( "Chris", "Cain", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 33, "6'8", 223, @@ -178,7 +178,7 @@ private void populatePlayers() { new Player( "Evan", "Williams", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 0, "6'7", 220, @@ -189,7 +189,7 @@ private void populatePlayers() { new Player( "Adam", "Tsang Hinton", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 11, "6'5", 213, @@ -200,7 +200,7 @@ private void populatePlayers() { new Player( "DJ", "Nix", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 23, "6'6", 216, @@ -211,7 +211,7 @@ private void populatePlayers() { new Player( "Ryan", "Kiachian", - new Position[] {Position.Forward, Position.Center}, + new Position[] {Position.FORWARD, Position.CENTER}, 3, "6'10", 228, @@ -222,7 +222,7 @@ private void populatePlayers() { new Player( "Darius", "Ervin", - new Position[] {Position.Guard}, + new Position[] {Position.GUARD}, 14, "5'8", 170, @@ -233,7 +233,7 @@ private void populatePlayers() { new Player( "Hayden", "Franson", - new Position[] {Position.Forward}, + new Position[] {Position.FORWARD}, 10, "6'8", 218, diff --git a/src/main/java/com/appdev/allin/contract/BasketballContractGenerator.java b/src/main/java/com/appdev/allin/contract/BasketballContractGenerator.java index a1b500b..d1f1812 100644 --- a/src/main/java/com/appdev/allin/contract/BasketballContractGenerator.java +++ b/src/main/java/com/appdev/allin/contract/BasketballContractGenerator.java @@ -92,7 +92,7 @@ public Contract generateContract(User user, Player player, Double buyPrice, Rari buyPrice, rarity, opposingTeam, - "src/main/resources/static/images/teams/" + opposingTeam + ".png", + "src/main/resources/static/images/teams/" + opposingTeam.toString().toLowerCase() + ".png", event, eventThreshold, LocalDate.now(), diff --git a/src/main/java/com/appdev/allin/contract/Event.java b/src/main/java/com/appdev/allin/contract/Event.java index 4a79a02..b21f08f 100644 --- a/src/main/java/com/appdev/allin/contract/Event.java +++ b/src/main/java/com/appdev/allin/contract/Event.java @@ -3,17 +3,17 @@ import java.util.concurrent.ThreadLocalRandom; public enum Event { - Points, - Minutes, - Field_Goals, - Three_Pointers, - Free_Throws, - Rebounds, - Assists, - Steals, - Blocks, - Turnovers, - Fouls; + POINTS, + MINUTES, + FIELD_GOALS, + THREE_POINTERS, + FREE_THROWS, + REBOUNDS, + ASSISTS, + STEALS, + BLOCKS, + TURNOVERS, + FOULS; public static Event getRandomEvent() { return values()[(int) (ThreadLocalRandom.current().nextDouble() * values().length)]; diff --git a/src/main/java/com/appdev/allin/contract/OpposingTeam.java b/src/main/java/com/appdev/allin/contract/OpposingTeam.java index a20b072..b8b19f7 100644 --- a/src/main/java/com/appdev/allin/contract/OpposingTeam.java +++ b/src/main/java/com/appdev/allin/contract/OpposingTeam.java @@ -3,28 +3,28 @@ import java.util.concurrent.ThreadLocalRandom; public enum OpposingTeam { - Lehigh, - Morrisville, - Fordham, - George, - Fullerton, - Utah, - Monmouth, - Lafayette, - Syracuse, - Siena, - Robert, - Colgate, - Baylor, - Columbia, - Penn, - Brown, - Wells, - Princeton, - Dartmouth, - Harvard, - Yale, - Ohio; + LEHIGH, + MORRISVILLE, + FORDHAM, + GEORGE, + FULLERTON, + UTAH, + MONMOUTH, + LAFAYETTE, + SYRACUSE, + SIENA, + ROBERT, + COLGATE, + BAYLOR, + COLUMBIA, + PENN, + BROWN, + WELLS, + PRINCETON, + DARTMOUTH, + HARVARD, + YALE, + OHIO; public static OpposingTeam getRandomOpposingTeam() { return values()[(int) (ThreadLocalRandom.current().nextDouble() * values().length)]; diff --git a/src/main/java/com/appdev/allin/contract/Rarity.java b/src/main/java/com/appdev/allin/contract/Rarity.java index 92dc389..8d5769c 100644 --- a/src/main/java/com/appdev/allin/contract/Rarity.java +++ b/src/main/java/com/appdev/allin/contract/Rarity.java @@ -3,21 +3,21 @@ import java.util.concurrent.ThreadLocalRandom; public enum Rarity { - Common, - Rare, - Epic, - Legendary; + COMMON, + RARE, + EPIC, + LEGENDARY; public static Rarity getRandomRarity() { double random = ThreadLocalRandom.current().nextDouble(); if (random < 0.55) { - return Common; + return COMMON; } else if (random < 0.8) { - return Rare; + return RARE; } else if (random < 0.95) { - return Epic; + return EPIC; } else { - return Legendary; + return LEGENDARY; } } } diff --git a/src/main/java/com/appdev/allin/player/Position.java b/src/main/java/com/appdev/allin/player/Position.java index e541e60..a0582df 100644 --- a/src/main/java/com/appdev/allin/player/Position.java +++ b/src/main/java/com/appdev/allin/player/Position.java @@ -1,7 +1,7 @@ package com.appdev.allin.player; public enum Position { - Guard, - Forward, - Center + GUARD, + FORWARD, + CENTER } diff --git a/src/main/java/com/appdev/allin/playerData/PlayerData.java b/src/main/java/com/appdev/allin/playerData/PlayerData.java index e74c5bc..a46e83b 100644 --- a/src/main/java/com/appdev/allin/playerData/PlayerData.java +++ b/src/main/java/com/appdev/allin/playerData/PlayerData.java @@ -269,27 +269,27 @@ public String toString() { public Integer getEvent(Event e) { switch (e) { - case Points: + case POINTS: return getPoints(); - case Minutes: + case MINUTES: return getMinutes(); - case Field_Goals: + case FIELD_GOALS: return getFieldGoals(); - case Three_Pointers: + case THREE_POINTERS: return getThreePointers(); - case Free_Throws: + case FREE_THROWS: return getFreeThrows(); - case Rebounds: + case REBOUNDS: return getRebounds(); - case Assists: + case ASSISTS: return getAssists(); - case Steals: + case STEALS: return getSteals(); - case Blocks: + case BLOCKS: return getBlocks(); - case Turnovers: + case TURNOVERS: return getTurnovers(); - case Fouls: + case FOULS: return getFouls(); default: return 0; diff --git a/src/main/java/com/appdev/allin/playerData/util/PopulatePlayerData.java b/src/main/java/com/appdev/allin/playerData/util/PopulatePlayerData.java index d651c7b..61b79e7 100644 --- a/src/main/java/com/appdev/allin/playerData/util/PopulatePlayerData.java +++ b/src/main/java/com/appdev/allin/playerData/util/PopulatePlayerData.java @@ -44,17 +44,17 @@ public void populate() throws IOException { int index = opposingTeamElement.get(0).text().indexOf("vs "); String opposingTeam = opposingTeamElement.get(0).text().substring(index + 3); if (opposingTeam.equals("SUNY Morrisville")) { - opposingTeam = "Morrisville"; + opposingTeam = "MORRISVILLE"; } else if (opposingTeam.equals("George Mason")) { - opposingTeam = "George"; + opposingTeam = "GEORGE"; } else if (opposingTeam.equals("Cal St. Fullerton")) { - opposingTeam = "Fullerton"; + opposingTeam = "FULLERTON"; } else if (opposingTeam.equals("Utah Valley")) { - opposingTeam = "Utah"; + opposingTeam = "UTAH"; } else if (opposingTeam.equals("Robert Morris")) { - opposingTeam = "Robert"; + opposingTeam = "ROBERT"; } else if (opposingTeam.equals("Ohio St.")) { - opposingTeam = "Ohio"; + opposingTeam = "OHIO"; } Elements sections = doc.getElementsByTag("section"); // check which section whose aria label contains Cornell @@ -93,7 +93,7 @@ public void populate() throws IOException { new PlayerData( player, gameDate, - OpposingTeam.valueOf(opposingTeam), + OpposingTeam.valueOf(opposingTeam.toUpperCase()), points, minutes, fieldGoalsMade, diff --git a/src/main/java/com/appdev/allin/utils/ImageProcessor.java b/src/main/java/com/appdev/allin/utils/ImageProcessor.java index b2a465b..a09790c 100644 --- a/src/main/java/com/appdev/allin/utils/ImageProcessor.java +++ b/src/main/java/com/appdev/allin/utils/ImageProcessor.java @@ -1,3 +1,133 @@ package com.appdev.allin.utils; -public class ImageProcessor {} +import com.drew.imaging.ImageMetadataReader; +import com.drew.metadata.Metadata; +import com.drew.metadata.exif.ExifIFD0Directory; + +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.io.File; +import java.io.IOException; + +import org.imgscalr.Scalr; + +public class ImageProcessor { + + /** + * Crops the given image to the specified width and height. + * If the specified dimensions are larger than the original image, + * the method ensures that the cropped area does not exceed the image bounds. + * + * @param originalImage The original BufferedImage to be cropped. + * @param targetWidth The desired width of the cropped image. + * @param targetHeight The desired height of the cropped image. + * @return A new BufferedImage representing the cropped portion of the original + * image. + */ + public static BufferedImage cropImage(BufferedImage originalImage, int targetWidth, int targetHeight) { + int originalWidth = originalImage.getWidth(); + int originalHeight = originalImage.getHeight(); + + int x = (originalWidth - targetWidth) / 2; + int y = (originalHeight - targetHeight) / 2; + + x = Math.max(0, x); + y = Math.max(0, y); + + targetWidth = Math.min(targetWidth, originalWidth - x); + targetHeight = Math.min(targetHeight, originalHeight - y); + + return originalImage.getSubimage(x, y, targetWidth, targetHeight); + } + + /** + * Corrects the orientation of an image based on its EXIF metadata. + * For images with metadata specifying an orientation, the image is rotated + * to match the correct orientation. If no metadata is available or if an error + * occurs, the original image is returned. + * + * @param image The BufferedImage to correct. + * @param file The image file used to retrieve EXIF metadata. + * @return A new BufferedImage with corrected orientation, or the original image + * if no correction is necessary. + * @throws IOException If an error occurs while reading the file. + */ + public static BufferedImage correctOrientation(BufferedImage image, File file) throws IOException { + try { + Metadata metadata = ImageMetadataReader.readMetadata(file); + if (metadata == null) { + System.err.println("No metadata found for orientation correction."); + return image; + } + ExifIFD0Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); + if (directory != null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { + int orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); + switch (orientation) { + case 6: + return rotateImage(image, 90); + case 3: + return rotateImage(image, 180); + case 8: + return rotateImage(image, 270); + default: + return image; + } + } + } catch (Exception e) { + System.err.println("Could not determine image orientation: " + e.getMessage()); + } + return image; + } + + /** + * Rotates image by [angle] degrees. + * + * @param image The original BufferedImage to rotate. + * @param angle The angle in degrees by which to rotate the image. Positive + * values rotate the image clockwise, and negative values rotate it + * counterclockwise. + * @return A new BufferedImage representing the rotated image. + */ + public static BufferedImage rotateImage(BufferedImage image, double angle) { + // Calculate the new image dimensions after rotation + double radians = Math.toRadians(angle); + int newWidth = (int) Math.abs(image.getWidth() * Math.cos(radians)) + + (int) Math.abs(image.getHeight() * Math.sin(radians)); + int newHeight = (int) Math.abs(image.getWidth() * Math.sin(radians)) + + (int) Math.abs(image.getHeight() * Math.cos(radians)); + + // Create a new image with the calculated dimensions + BufferedImage rotatedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = rotatedImage.createGraphics(); + + // Set the rendering hints for better quality + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Calculate the rotation point (center of the original image) + int x = (newWidth - image.getWidth()) / 2; + int y = (newHeight - image.getHeight()) / 2; + + // Rotate around the center of the new image + g2d.rotate(radians, newWidth / 2.0, newHeight / 2.0); + g2d.drawImage(image, x, y, null); + g2d.dispose(); + + System.out.println("Image rotated by " + angle + " degrees."); + return rotatedImage; + } + + /** + * Scales image to target width and height. + * + * @param originalImage The original BufferedImage to be scaled. + * @param targetWidth The desired width of the scaled image. + * @param targetHeight The desired height of the scaled image. + * @return A new BufferedImage representing the scaled image. + */ + public static BufferedImage scaleImage(BufferedImage originalImage, int targetWidth, int targetHeight) { + return Scalr.resize(originalImage, Scalr.Method.ULTRA_QUALITY, targetWidth, targetHeight); + } +} \ No newline at end of file diff --git a/src/test/java/com/appdev/allin/AllInApplicationTests.java b/src/test/java/com/appdev/allin/AllInApplicationTests.java index 3fa5041..035e7dd 100644 --- a/src/test/java/com/appdev/allin/AllInApplicationTests.java +++ b/src/test/java/com/appdev/allin/AllInApplicationTests.java @@ -127,7 +127,7 @@ public void testGenerateContract() { new Player( "LeBron", "James", - new Position[] {Position.Center}, + new Position[] {Position.CENTER}, 23, "6'9", 250, @@ -135,7 +135,7 @@ public void testGenerateContract() { "St. Vincent-St. Mary", "src/main/resources/static/images/players/default.jpg"); - Contract contract = contractGenerator.generateContract(user, player, 100.0, Rarity.Common); + Contract contract = contractGenerator.generateContract(user, player, 100.0, Rarity.COMMON); System.out.println("Contract: " + contract.toString()); } } diff --git a/src/test/java/com/appdev/allin/ContractGeneratorTest.java b/src/test/java/com/appdev/allin/ContractGeneratorTest.java index 1f60749..adcd6b6 100644 --- a/src/test/java/com/appdev/allin/ContractGeneratorTest.java +++ b/src/test/java/com/appdev/allin/ContractGeneratorTest.java @@ -127,14 +127,14 @@ public void testGenerateContract() { new Player( "LeBron", "James", - new Position[] {Position.Center}, + new Position[] {Position.CENTER}, 23, "6'9", 250, "Akron, OH", "St. Vincent-St. Mary", "src/main/resources/static/images/players/default.jpg"); - Contract contract = contractGenerator.generateContract(user, player, 100.0, Rarity.Common); + Contract contract = contractGenerator.generateContract(user, player, 100.0, Rarity.COMMON); System.out.println("Contract: " + contract.toString()); } }