diff --git a/impl/src/java/org/sakaiproject/profile2/conversion/ProfileConverter.java b/impl/src/java/org/sakaiproject/profile2/conversion/ProfileConverter.java index e8633bc..7ef303f 100644 --- a/impl/src/java/org/sakaiproject/profile2/conversion/ProfileConverter.java +++ b/impl/src/java/org/sakaiproject/profile2/conversion/ProfileConverter.java @@ -101,7 +101,7 @@ public class ProfileConverter { String mimeType = "image/jpeg"; //scale the main image - byte[] imageMain = ProfileUtils.scaleImage(image, ProfileConstants.MAX_IMAGE_XY); + byte[] imageMain = ProfileUtils.scaleImage(image, ProfileConstants.MAX_IMAGE_XY, mimeType); //create resource ID String mainResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_MAIN); @@ -117,7 +117,7 @@ public class ProfileConverter { * THUMBNAIL PROFILE IMAGE */ //scale image - byte[] imageThumbnail = ProfileUtils.scaleImage(image, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY); + byte[] imageThumbnail = ProfileUtils.scaleImage(image, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY, mimeType); //create resource ID String thumbnailResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_THUMBNAIL); @@ -229,7 +229,7 @@ public class ProfileConverter { inputStream = openConnection.getInputStream(); // Convert the image. byte[] sourceImage = IOUtils.toByteArray(inputStream); - byte[] imageMain = ProfileUtils.scaleImage(sourceImage, ProfileConstants.MAX_IMAGE_XY); + byte[] imageMain = ProfileUtils.scaleImage(sourceImage, ProfileConstants.MAX_IMAGE_XY, mimeType); //create resource ID String mainResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_MAIN); @@ -243,7 +243,7 @@ public class ProfileConverter { * THUMBNAIL PROFILE IMAGE */ //scale image - byte[] imageThumbnail = ProfileUtils.scaleImage(imageMain, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY); + byte[] imageThumbnail = ProfileUtils.scaleImage(imageMain, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY, mimeType); //create resource ID String thumbnailResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_THUMBNAIL); diff --git a/impl/src/java/org/sakaiproject/profile2/logic/ProfileImageLogicImpl.java b/impl/src/java/org/sakaiproject/profile2/logic/ProfileImageLogicImpl.java index a881d47..4a9297a 100644 --- a/impl/src/java/org/sakaiproject/profile2/logic/ProfileImageLogicImpl.java +++ b/impl/src/java/org/sakaiproject/profile2/logic/ProfileImageLogicImpl.java @@ -235,7 +235,7 @@ public class ProfileImageLogicImpl implements ProfileImageLogic { * MAIN PROFILE IMAGE */ //scale image - imageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_IMAGE_XY); + imageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_IMAGE_XY, mimeType); //create resource ID String mainResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_MAIN); @@ -250,7 +250,7 @@ public class ProfileImageLogicImpl implements ProfileImageLogic { * THUMBNAIL PROFILE IMAGE */ //scale image - imageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY); + imageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY, mimeType); //create resource ID String thumbnailResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_THUMBNAIL); @@ -344,7 +344,7 @@ public class ProfileImageLogicImpl implements ProfileImageLogic { // create resource ID String mainResourcePath = sakaiProxy.getProfileGalleryImagePath(userUuid, imageId); - byte[] scaledImageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_GALLERY_IMAGE_XY); + byte[] scaledImageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_GALLERY_IMAGE_XY, mimeType); // save image if (!sakaiProxy.saveFile(mainResourcePath, userUuid, fileName, mimeType,scaledImageBytes)) { @@ -353,7 +353,7 @@ public class ProfileImageLogicImpl implements ProfileImageLogic { } // create thumbnail - byte[] thumbnailBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_GALLERY_THUMBNAIL_IMAGE_XY); + byte[] thumbnailBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_GALLERY_THUMBNAIL_IMAGE_XY, mimeType); String thumbnailResourcePath = sakaiProxy.getProfileGalleryThumbnailPath(userUuid, imageId); sakaiProxy.saveFile(thumbnailResourcePath, userUuid, fileName, mimeType,thumbnailBytes); diff --git a/util/pom.xml b/util/pom.xml index c484dec..858c34d 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -28,6 +28,13 @@ commons-lang provided + + + org.imgscalr + imgscalr-lib + 4.2 + compile + diff --git a/util/src/java/org/sakaiproject/profile2/util/ProfileUtils.java b/util/src/java/org/sakaiproject/profile2/util/ProfileUtils.java index 5aee979..78f81a9 100644 --- a/util/src/java/org/sakaiproject/profile2/util/ProfileUtils.java +++ b/util/src/java/org/sakaiproject/profile2/util/ProfileUtils.java @@ -21,6 +21,7 @@ import java.awt.Image; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigDecimal; @@ -30,6 +31,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -37,6 +39,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import javax.imageio.ImageIO; import javax.swing.ImageIcon; import org.apache.commons.lang.StringEscapeUtils; @@ -44,6 +47,7 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.WordUtils; import org.apache.log4j.Logger; +import org.imgscalr.Scalr; import org.sakaiproject.util.FormattedText; import org.sakaiproject.util.ResourceLoader; @@ -86,71 +90,58 @@ public class ProfileUtils { * @param imageData bytes of the original image * @param maxSize maximum dimension in px that the image should have on any one side */ - public static byte[] scaleImage(byte[] imageData, int maxSize) { - - log.debug("Scaling image..."); - - // Get the image - Image inImage = new ImageIcon(imageData).getImage(); - - // Determine the scale (we could change this to only determine scale from one dimension, ie the width only?) - double scale = (double) maxSize / (double) inImage.getHeight(null); - if (inImage.getWidth(null) > inImage.getHeight(null)) { - scale = (double) maxSize / (double) inImage.getWidth(null); - } - - /* - log.debug("===========Image scaling============"); - log.debug("WIDTH: " + inImage.getWidth(null)); - log.debug("HEIGHT: " + inImage.getHeight(null)); - log.debug("SCALE: " + scale); - log.debug("========End of image scaling========"); - */ - - //if image is smaller than desired image size (ie scale is larger) just return the original image bytes - if (scale >= 1.0d) { - return imageData; - } - - - - // Determine size of new image. - // One of the dimensions should equal maxSize. - int scaledW = (int) (scale * inImage.getWidth(null)); - int scaledH = (int) (scale * inImage.getHeight(null)); - - // Create an image buffer in which to paint on. - BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB); - - // Set the scale. - AffineTransform tx = new AffineTransform(); - - //scale - tx.scale(scale, scale); - - // Paint image. - Graphics2D g2d = outImage.createGraphics(); - g2d.setRenderingHint( - RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON - ); - g2d.drawImage(inImage, tx, null); - g2d.dispose(); - - // JPEG-encode the image - // and write to file. - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); - encoder.encode(outImage); - os.close(); - log.debug("Scaling done."); - } catch (IOException e) { - log.error("Scaling image failed."); - } - return os.toByteArray(); + public static byte[] scaleImage(byte[] imageData, int maxSize, String mimeType) { + + byte[] scaledImageBytes = null; + ByteArrayInputStream in = new ByteArrayInputStream(imageData); + try { + //convert original image to inputstream + + //original buffered image + BufferedImage originalImage = ImageIO.read(in); + + //scale the image using the imgscalr library + BufferedImage scaledImage = Scalr.resize(originalImage, maxSize); + + //convert BufferedImage to byte array + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(scaledImage, getInformalFormatForMimeType(mimeType), baos); + baos.flush(); + scaledImageBytes = baos.toByteArray(); + baos.close(); + + } catch (Exception e) { + log.error("Scaling image failed.", e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) {} //Ignore + } + } + + return scaledImageBytes; + } + public static String getInformalFormatForMimeType(String mimeType){ + Map formats = new HashMap(); + formats.put("image/jpeg", "jpg"); + formats.put("image/gif", "gif"); + formats.put("image/png", "png"); + formats.put("image/x-png", "png"); + formats.put("image/pjpeg", "jpg"); + formats.put("image/jpg", "jpg"); + + String format = formats.get(mimeType); + + if(format != null) { + return format; + } + return "jpg"; +} + + /** * Convert a Date into a String according to format *