package org.fluxtream.core.utils; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.IOException; import com.drew.imaging.ImageProcessingException; import org.fluxtream.core.domain.Geolocation; import org.fluxtream.core.images.Image; import org.fluxtream.core.images.ImageType; import junit.framework.Assert; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.NotNull; import org.junit.Test; /** * <p> * <code>ImageUtilsTest</code> tests the {@link ImageUtils} class. * </p> * * @author Chris Bartley (bartley@cmu.edu) */ public class ImageUtilsTest { private static final byte[] IMAGE_1 = readFileAsBytes("/images/test_image1.jpg"); private static final byte[] IMAGE_2 = readFileAsBytes("/images/test_image2.jpg"); private static final byte[] IMAGE_3 = readFileAsBytes("/images/test_image3.png"); private static final byte[] IMAGE_4 = readFileAsBytes("/images/test_image4.gif"); private static final byte[] IMAGE_5 = readFileAsBytes("/images/test_image5.tiff"); private static final byte[] IMAGE_6 = readFileAsBytes("/images/test_image6.jpg"); private static final byte[] NOT_AN_IMAGE = "This is not an image".getBytes(); private static final Dimension IMAGE_1_EXPECTED_SIZE = new Dimension(265, 284); private static final Dimension IMAGE_2_EXPECTED_SIZE = new Dimension(2448, 3264); private static final Dimension IMAGE_3_EXPECTED_SIZE = new Dimension(1024, 1365); private static final Dimension IMAGE_4_EXPECTED_SIZE = new Dimension(265, 284); private static final Dimension IMAGE_6_EXPECTED_SIZE = new Dimension(776, 909); private static byte[] readFileAsBytes(final String filePath) { byte[] imageBytes; try { imageBytes = IOUtils.toByteArray(HashUtilsTest.class.getResourceAsStream(filePath)); } catch (IOException e) { imageBytes = "Failed to read the image file".getBytes(); Assert.fail("IOException while trying to read the file for IMAGE_BYTES:" + e); } return imageBytes; } @Test public void testIsSupportedImage() { Assert.assertTrue(ImageUtils.isSupportedImage(IMAGE_1)); Assert.assertTrue(ImageUtils.isSupportedImage(IMAGE_2)); Assert.assertTrue(ImageUtils.isSupportedImage(IMAGE_3)); Assert.assertTrue(ImageUtils.isSupportedImage(IMAGE_4)); Assert.assertFalse(ImageUtils.isSupportedImage(IMAGE_5)); // TIFFs are not supported Assert.assertTrue(ImageUtils.isSupportedImage(IMAGE_6)); Assert.assertFalse(ImageUtils.isSupportedImage(NOT_AN_IMAGE)); // not actually an image } @Test public void testCreateThumbnail() throws Exception { Assert.assertNull(ImageUtils.createJpegThumbnail(null, -1)); Assert.assertNull(ImageUtils.createJpegThumbnail(null, 0)); Assert.assertNull(ImageUtils.createJpegThumbnail(null, 100)); Assert.assertNull(ImageUtils.createJpegThumbnail(new byte[]{}, -1)); Assert.assertNull(ImageUtils.createJpegThumbnail(new byte[]{}, 0)); Assert.assertNull(ImageUtils.createJpegThumbnail(new byte[]{}, 100)); Assert.assertNull(ImageUtils.createJpegThumbnail(IMAGE_1, -1)); Assert.assertNull(ImageUtils.createJpegThumbnail(IMAGE_1, 0)); Assert.assertNull(ImageUtils.createJpegThumbnail(NOT_AN_IMAGE, 100)); testCreateThumbnailHelper(IMAGE_1, 50, new Dimension(47, 50)); testCreateThumbnailHelper(IMAGE_1, 100, new Dimension(93, 100)); testCreateThumbnailHelper(IMAGE_1, (int)Math.max(IMAGE_1_EXPECTED_SIZE.getHeight(), IMAGE_1_EXPECTED_SIZE.getWidth()), IMAGE_1_EXPECTED_SIZE); testCreateThumbnailHelper(IMAGE_2, 50, new Dimension(38, 50)); testCreateThumbnailHelper(IMAGE_2, 100, new Dimension(75, 100)); testCreateThumbnailHelper(IMAGE_2, (int)Math.max(IMAGE_2_EXPECTED_SIZE.getHeight(), IMAGE_2_EXPECTED_SIZE.getWidth()), IMAGE_2_EXPECTED_SIZE); testCreateThumbnailHelper(IMAGE_3, 50, new Dimension(38, 50)); testCreateThumbnailHelper(IMAGE_3, 100, new Dimension(75, 100)); testCreateThumbnailHelper(IMAGE_3, (int)Math.max(IMAGE_3_EXPECTED_SIZE.getHeight(), IMAGE_3_EXPECTED_SIZE.getWidth()), IMAGE_3_EXPECTED_SIZE); testCreateThumbnailHelper(IMAGE_4, 50, new Dimension(47, 50)); testCreateThumbnailHelper(IMAGE_4, 100, new Dimension(93, 100)); testCreateThumbnailHelper(IMAGE_4, (int)Math.max(IMAGE_4_EXPECTED_SIZE.getHeight(), IMAGE_4_EXPECTED_SIZE.getWidth()), IMAGE_4_EXPECTED_SIZE); testCreateThumbnailHelper(IMAGE_6, 50, new Dimension(43, 50)); testCreateThumbnailHelper(IMAGE_6, 100, new Dimension(85, 100)); testCreateThumbnailHelper(IMAGE_6, (int)Math.max(IMAGE_6_EXPECTED_SIZE.getHeight(), IMAGE_6_EXPECTED_SIZE.getWidth()), IMAGE_6_EXPECTED_SIZE); } private void testCreateThumbnailHelper(@NotNull final byte[] imageBytes, final int lengthOfLongestSideInPixels, @NotNull final Dimension expectedDimension) throws IOException { final Image thumbnail = ImageUtils.createJpegThumbnail(imageBytes, lengthOfLongestSideInPixels); Assert.assertNotNull(thumbnail); Assert.assertEquals(expectedDimension, new Dimension(thumbnail.getWidth(), thumbnail.getHeight())); } @Test public void testConversion() throws Exception { Assert.assertNull(ImageUtils.convertToBufferedImage(null)); Assert.assertNull(ImageUtils.convertToBufferedImage(new byte[]{})); final BufferedImage image1 = ImageUtils.convertToBufferedImage(IMAGE_1); final BufferedImage image2 = ImageUtils.convertToBufferedImage(IMAGE_2); final BufferedImage image3 = ImageUtils.convertToBufferedImage(IMAGE_3); final BufferedImage image4 = ImageUtils.convertToBufferedImage(IMAGE_4); final BufferedImage image5 = ImageUtils.convertToBufferedImage(IMAGE_5); final BufferedImage image6 = ImageUtils.convertToBufferedImage(IMAGE_6); final BufferedImage image7 = ImageUtils.convertToBufferedImage(NOT_AN_IMAGE); Assert.assertNotNull(image1); Assert.assertNotNull(image2); Assert.assertNotNull(image3); Assert.assertNotNull(image4); // TIFFs apparently may or may not be supported, depending on platform, so no null assert here. Assert.assertNotNull(image6); Assert.assertNull(image7); Assert.assertNull(ImageUtils.convertToJpegByteArray(null)); Assert.assertNotNull(ImageUtils.convertToJpegByteArray(image1)); Assert.assertNotNull(ImageUtils.convertToJpegByteArray(image2)); Assert.assertNotNull(ImageUtils.convertToJpegByteArray(image3)); Assert.assertNotNull(ImageUtils.convertToJpegByteArray(image4)); Assert.assertNotNull(ImageUtils.convertToJpegByteArray(image6)); if (image5 != null) { Assert.assertNotNull(ImageUtils.convertToJpegByteArray(image5)); } } @Test public void testExtractLatLong() throws Exception { final double delta = 0.00001; Assert.assertNull(ImageUtils.getGeolocation(IMAGE_1)); final Geolocation geolocation1 = ImageUtils.getGeolocation(IMAGE_2); Assert.assertNotNull(geolocation1); Assert.assertEquals(40.44283333333333, geolocation1.getLatitude(), delta); Assert.assertEquals(-79.94633333333333, geolocation1.getLongitude(), delta); Assert.assertEquals(318.99533, geolocation1.getHeading(), delta); Assert.assertEquals("T", geolocation1.getHeadingRef()); Assert.assertEquals(318.00183, geolocation1.getAltitude(), delta); Assert.assertEquals((Integer)0, geolocation1.getAltitudeRef()); Assert.assertEquals(null, geolocation1.getGpsPrecision()); Assert.assertEquals(null, geolocation1.getGpsDatestamp()); Assert.assertEquals("20:32:31 UTC", geolocation1.getGpsTimestamp()); try { ImageUtils.getGeolocation(IMAGE_3); Assert.fail("ImageUtils.getGeolocation() should fail for IMAGE_3 since the image type is not supported."); } catch (ImageProcessingException e) { // nothing to do } catch (IOException e) { Assert.fail("Should not get an IOException for calling ImageUtils.getGeolocation() on IMAGE_3."); } try { ImageUtils.getGeolocation(IMAGE_4); Assert.fail("ImageUtils.getGeolocation() should fail for IMAGE_4 since the image type is not supported."); } catch (ImageProcessingException e) { // nothing to do } catch (IOException e) { Assert.fail("Should not get an IOException for calling ImageUtils.getGeolocation() on IMAGE_4."); } try { ImageUtils.getGeolocation(IMAGE_4); Assert.fail("ImageUtils.getGeolocation() should fail for IMAGE_4 since the image type is not supported."); } catch (ImageProcessingException e) { // nothing to do } catch (IOException e) { Assert.fail("Should not get an IOException for calling ImageUtils.getGeolocation() on IMAGE_4."); } Assert.assertNull(ImageUtils.getGeolocation(IMAGE_5)); final Geolocation geolocation2 = ImageUtils.getGeolocation(IMAGE_6); Assert.assertNotNull(geolocation2); Assert.assertEquals(45.50066666666667, geolocation2.getLatitude(), delta); Assert.assertEquals(9.110333333333333, geolocation2.getLongitude(), delta); Assert.assertEquals(null, geolocation2.getHeading()); Assert.assertEquals(null, geolocation2.getHeadingRef()); Assert.assertEquals(217, geolocation2.getAltitude(), delta); Assert.assertEquals((Integer)0, geolocation2.getAltitudeRef()); Assert.assertEquals(null, geolocation2.getGpsPrecision()); Assert.assertEquals("2011:05:06", geolocation2.getGpsDatestamp()); Assert.assertEquals("7:59:48 UTC", geolocation2.getGpsTimestamp()); try { ImageUtils.getGeolocation(NOT_AN_IMAGE); Assert.fail("ImageUtils.getGeolocation() should fail for NOT_AN_IMAGE since the image type is not supported."); } catch (ImageProcessingException e) { // nothing to do } catch (IOException e) { Assert.fail("Should not get an IOException for calling ImageUtils.getGeolocation() on NOT_AN_IMAGE."); } Assert.assertNull(ImageUtils.getGeolocation(null)); Assert.assertNull(ImageUtils.getGeolocation(new byte[]{})); } @Test public void testGetImageType() throws IOException { Assert.assertEquals(ImageType.JPEG, ImageUtils.getImageType(IMAGE_1)); Assert.assertEquals(ImageType.JPEG, ImageUtils.getImageType(IMAGE_2)); Assert.assertEquals(ImageType.PNG, ImageUtils.getImageType(IMAGE_3)); Assert.assertEquals(ImageType.GIF, ImageUtils.getImageType(IMAGE_4)); Assert.assertNull(ImageUtils.getImageType(IMAGE_5)); Assert.assertEquals(ImageType.JPEG, ImageUtils.getImageType(IMAGE_6)); Assert.assertNull(ImageUtils.getImageType(NOT_AN_IMAGE)); Assert.assertNull(ImageUtils.getImageType((byte[])null)); Assert.assertNull(ImageUtils.getImageType(new byte[]{})); } }