/** * Method for resizing images when images are stored in the database. * * <p>Convenience method that returns a scaled instance of the provided image. This method never * resizes by more than 50% since resizing by more than that amount causes quality issues with the * BICUBIC and BILINEAR algorithms. * * <p>Based on examples from the GraphicsUtilities sample from the book "Filthy Rich Clients" by * Chet Haase and Romain Guy (http://filthyrichclients.org/). That source is dual licensed: LGPL * (Sun and Romain Guy) and BSD (Romain Guy). * * @param fileId The file identifier for the original image to be scaled. * @param fileVersionId The ID of the image revision being resized, or -1 if the current image * revision is being resized. * @param targetWidth the desired width of the scaled instance in pixels. * @param targetHeight the desired height of the scaled instance in pixels. * @return a dimensions of scaled image */ public static Dimension resizeImage( int fileId, int fileVersionId, int targetWidth, int targetHeight) throws IOException { long start = System.currentTimeMillis(); ImageData imageData = ImageProcessor.loadImage(fileId, fileVersionId); BufferedImage tmp = ImageIO.read(new ByteArrayInputStream(imageData.data)); if (tmp == null) { throw new IOException( "JDK is unable to process image data, possibly indicating data corruption: " + fileId); } BufferedImage resized = ImageProcessor.resizeImage(tmp, targetWidth, targetHeight); int pos = imageData.mimeType.lastIndexOf('/'); if (pos == -1 || (pos + 1) >= imageData.mimeType.length()) { throw new IOException("Unknown image file type " + imageData.mimeType); } String imageType = imageData.mimeType.substring(pos + 1).toLowerCase(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); boolean result = ImageIO.write(resized, imageType, baos); if (!result) { throw new IOException( "No appropriate writer found when writing image: " + imageData.fileVersionId); } baos.close(); imageData.width = resized.getWidth(); imageData.height = resized.getHeight(); imageData.data = baos.toByteArray(); saveImage(imageData); if (logger.isDebugEnabled()) { long current = System.currentTimeMillis(); String message = "Image resize time (" + ((current - start) / 1000.000) + " s), dimensions: " + targetWidth + "x" + targetHeight + " for fileId: " + fileId; logger.debug(message); } return new Dimension(imageData.width, imageData.height); }
/** * Convenience method that returns a scaled instance of the provided image. This method never * resizes by more than 50% since resizing by more than that amount causes quality issues with the * BICUBIC and BILINEAR algorithms. * * <p>Based on examples from the GraphicsUtilities sample from the book "Filthy Rich Clients" by * Chet Haase and Romain Guy (http://filthyrichclients.org/). That source is dual licensed: LGPL * (Sun and Romain Guy) and BSD (Romain Guy). * * @param fileId The file identifier for the original image to be scaled. * @param targetWidth the desired width of the scaled instance in pixels. * @param targetHeight the desired height of the scaled instance in pixels. * @return a dimensions of scaled image */ public static Dimension resizeImage(int fileId, int targetWidth, int targetHeight) throws IOException { long start = System.currentTimeMillis(); ImageData imageData = ImageProcessor.loadImage(fileId); BufferedImage tmp = ImageIO.read(new ByteArrayInputStream(imageData.data)); if (tmp == null) { throw new IOException( "JDK is unable to process image data, possibly indicating data corruption: " + fileId); } int type = (tmp.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; int width = tmp.getWidth(); int height = tmp.getHeight(); BufferedImage resized = tmp; do { width /= 2; if (width < targetWidth) { width = targetWidth; } height /= 2; if (height < targetHeight) { height = targetHeight; } tmp = new BufferedImage(width, height, type); Graphics2D g2 = tmp.createGraphics(); g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2.drawImage(resized, 0, 0, width, height, null); g2.dispose(); resized = tmp; } while (width != targetWidth || height != targetHeight); if (logger.isDebugEnabled()) { long current = System.currentTimeMillis(); String message = "Image resize time (" + ((current - start) / 1000.000) + " s), dimensions: " + targetWidth + "x" + targetHeight + " for fileId: " + fileId; logger.debug(message); } int pos = imageData.mimeType.lastIndexOf('/'); if (pos == -1 || (pos + 1) >= imageData.mimeType.length()) { throw new IOException("Unknown image file type " + imageData.mimeType); } String imageType = imageData.mimeType.substring(pos + 1).toLowerCase(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); boolean result = ImageIO.write(resized, imageType, baos); if (!result) { throw new IOException( "No appropriate writer found when writing image: " + imageData.fileVersionId); } baos.close(); imageData.width = resized.getWidth(); imageData.height = resized.getHeight(); imageData.data = baos.toByteArray(); saveImage(imageData); return new Dimension(imageData.width, imageData.height); }