/* * Copyright 2012 buddycloud * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.buddycloud.mediaserver.business.util; import com.mortennobel.imagescaling.ResampleOp; import net.coobird.thumbnailator.Thumbnails; import net.coobird.thumbnailator.geometry.Positions; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.FileImageOutputStream; import javax.imageio.stream.MemoryCacheImageOutputStream; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Arrays; public class ImageUtils { private ImageUtils() { } private static ImageWriteParam getParams(ImageWriter writer) { ImageWriteParam param = writer.getDefaultWriteParam(); try { // Do not compress before output the file param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(1.0f); } catch (Throwable ignored) { // If the format does not support setting compression mode } return param; } private static void writeToFile(BufferedImage image, String format, File file) throws IOException { ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next(); ImageWriteParam param = getParams(writer); writer.setOutput(new FileImageOutputStream(file)); writer.write(null, new IIOImage(image, null, null), param); } public static File storeImageIntoFile(BufferedImage image, int width, int height, String imageFormat, String pathToStore) throws IOException { ResampleOp resampleOp = getResampleOp(image, width, height); BufferedImage rescaled = resampleOp.filter(image, null); File output = new File(pathToStore); writeToFile(rescaled, imageFormat, output); return output; } public static byte[] imageToBytes(BufferedImage image, String imageFormat) throws IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ImageWriter writer = ImageIO.getImageWritersByFormatName(imageFormat).next(); ImageWriteParam param = getParams(writer); writer.setOutput(new MemoryCacheImageOutputStream(stream)); writer.write(null, new IIOImage(image, null, null), param); stream.flush(); byte[] imageInByte = stream.toByteArray(); stream.close(); return imageInByte; } public static BufferedImage createImagePreview(File image, int width, int height) throws IOException { BufferedImage bufferedImage = ImageIO.read(image); if (bufferedImage.getWidth() < width || bufferedImage.getHeight() < height) { return bufferedImage; } ResampleOp resampleOp = getResampleOp(bufferedImage, width, height); return resampleOp.filter(bufferedImage, null); } public static BufferedImage createImagePreview(BufferedImage img, int width, int height) { ResampleOp resampleOp = getResampleOp(img, width, height); return resampleOp.filter(img, null); } public static BufferedImage cropMaximumSquare(BufferedImage img) throws IOException { int smallerSide = img.getHeight() <= img.getWidth() ? img.getHeight() : img.getWidth(); final BufferedImage cropedImg = Thumbnails.of(img).sourceRegion(Positions.CENTER, smallerSide, smallerSide).size(smallerSide, smallerSide).asBufferedImage(); return cropedImg; } private static ResampleOp getResampleOp(BufferedImage img, int maxWidth, int maxHeight) { // java-image-scaling throws a RuntimeException if width or height are smaller than 3 maxWidth = Math.max(maxWidth, 4); maxHeight = Math.max(maxHeight, 4); double ratio = Math.min((double) maxWidth / img.getWidth(), (double) maxHeight / img.getHeight()); double width = ratio * img.getWidth(); double height = ratio * img.getHeight(); return new ResampleOp((int) width, (int) height); } public static boolean isImage(String extension) { if (null == extension) { return false; } return Arrays.binarySearch(FORMATS, extension.toLowerCase()) >= 0; } public static boolean isSquare(BufferedImage img) { return img.getHeight() == img.getWidth(); } private static final String[] FORMATS = { "001", "2bp", "360", "3fr", "411", "73i", "8pbs", "8xi", "abm", "acr", "adc", "afx", "agif", "agp", "aic", "ais", "albm", "apd", "apm", "apng", "aps", "apx", "ari", "arr", "art", "artwork", "arw", "arw", "asw", "avatar", "awd", "awd", "bay", "blkrt", "blz", "bm2", "bmc", "bmf", "bmp", "bmx", "bmz", "brk", "brn", "brt", "bss", "bti", "c4", "cal", "cals", "cam", "can", "cd5", "cdc", "cdg", "ce", "cimg", "cin", "cit", "colz", "cpc", "cpd", "cpg", "cps", "cpt", "cpx", "cr2", "crw", "csf", "ct", "cut", "dc2", "dcm", "dcr", "dcx", "ddb", "dds", "ddt", "dib", "dicom", "djv", "djvu", "dm3", "dng", "dpx", "drz", "dt2", "dtw", "dvl", "ecw", "epp", "erf", "exr", "fac", "face", "fal", "fax", "fbm", "fff", "fil", "fits", "fpg", "fpos", "fpx", "frm", "g3", "gbr", "gcdp", "gfb", "gfie", "gif", "gih", "gim", "gmbck", "gp4", "gpd", "gro", "grob", "gry", "hdp", "hdr", "hf", "hpi", "hr", "hrf", "i3d", "ic1", "ic2", "ic3", "ica", "icb", "icn", "icon", "icpr", "iiq", "ilbm", "img", "imj", "info", "ink", "int", "ipx", "itc2", "ithmb", "ivr", "ivue", "iwi", "j", "j2c", "j2k", "jas", "jb2", "jbf", "jbig", "jbig2", "jbmp", "jbr", "jfi", "jfif", "jia", "jif", "jiff", "jng", "jp2", "jpc", "jpd", "jpe", "jpeg", "jpf", "jpg", "jpg2", "jps", "jpx", "jtf", "jwl", "jxr", "kdc", "kdi", "kdk", "kfx", "kic", "kodak", "kpg", "lbm", "lif", "ljp", "mac", "mat", "max", "mbm", "mcs", "mef", "met", "mic", "mip", "mix", "mng", "mnr", "mos", "mpf", "mpo", "mrb", "mrw", "mrxs", "msk", "msp", "mxi", "myl", "ncd", "ncr", "nct", "nef", "neo", "nrw", "oc3", "oc4", "oc5", "oci", "odi", "omf", "orf", "ota", "otb", "oti", "pac", "pal", "pap", "pat", "pbm", "pc1", "pc2", "pc3", "pcd", "pcx", "pdd", "pdn", "pe4", "pe4", "pef", "pfi", "pfr", "pgf", "pgm", "pi1", "pi2", "pi2", "pi3", "pi4", "pi5", "pi6", "pic", "pic", "pic", "picnc", "pict", "pictclipping", "pix", "pix", "pixadex", "pjpeg", "pjpg", "pm", "pm3", "pmg", "png", "pni", "pnm", "pns", "pnt", "pntg", "pop", "pov", "pov", "pp4", "pp5", "ppf", "ppm", "prw", "psb", "psd", "psdx", "pse", "psf", "psp", "pspbrush", "pspimage", "ptg", "ptk", "ptx", "ptx", "pvr", "pwp", "px", "pxd", "pxicon", "pxm", "pxr", "pzp", "qif", "qmg", "qti", "qtif", "raf", "ras", "raw", "rcl", "rcu", "rgb", "rgb", "ric", "rif", "riff", "rix", "rle", "rli", "rpf", "rri", "rs", "rsb", "rsr", "rw2", "rwl", "s2mv", "sar", "scg", "sci", "scn", "scp", "sct", "scu", "sdr", "sep", "sfc", "sff", "sfw", "sgi", "shg", "sid", "sig", "sim", "skitch", "skm", "skypeemoticonset", "sld", "smp", "sob", "spa", "spc", "spe", "sph", "spiff", "spj", "spp", "spr", "sprite", "spu", "sr", "sr2", "srf", "srw", "ste", "sumo", "sun", "suniff", "sup", "sva", "t2b", "taac", "tb0", "tex", "tfc", "tg4", "tga", "thm", "thm", "thumb", "tif", "tif", "tiff", "tjp", "tn", "tn1", "tn2", "tn3", "tny", "tpf", "tpi", "tps", "trif", "tub", "u", "ufo", "urt", "usertile-ms", "v", "vda", "vff", "vic", "viff", "vna", "vss", "vst", "wb1", "wbc", "wbd", "wbm", "wbmp", "wbz", "wdp", "webp", "wi", "wic", "wmp", "wpb", "wpe", "wvl", "x3f", "xbm", "xcf", "xpm", "xwd", "y", "ysp", "yuv", "zif" }; }