/* Dateiverwaltung - File management in your browser Copyright (C) 2017 Ulrich Hilger, http://uhilger.de This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.wbx; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.net.FileNameMap; import java.net.URLConnection; import javax.imageio.ImageIO; /** * Methoden zur Verkleinerung von Bildern */ public class Bild { public static final int WINZIG = 0; public static final int KLEIN = 1; public static final int SEMI = 2; public static final int MITTEL = 3; public static final int GROSS = 4; public static final String[] GRNAME = {"-w", "-k", "-s", "-m", "-g"}; public static final int[] GR = {120, 240, 500, 700, 1200}; public void writeImageStream(Image image, int gr, String mimeType, OutputStream out) throws InterruptedException, IOException { ImageIO.write(getReducedImage(image, gr, mimeType), imgType(mimeType), out); } /** * * @param image * @param gr * @param mimeType * @param vName Name der verkleinerten Datei * @throws InterruptedException * @throws IOException */ public void writeImageFile(Image image, int gr, String mimeType, String vName) throws InterruptedException, IOException { ImageIO.write(getReducedImage(image, gr, mimeType), imgType(mimeType), new File(vName)); } private BufferedImage getReducedImage(Image image, int gr, String mimeType) throws InterruptedException, IOException { BufferedImage img; int q = 90; float sh = 0.f; if (mimeType.contains("jpeg")) { img = getReducedImage2(image, gr, gr, q, sh, false); } else { img = getReducedImage2(image, gr, gr, q, sh, true); } return img; } /** * Eine in Groesse und Qualitaet verringerte Bilddatei erzeugen * * @param image Ablageort und Name der Bilddatei * @param width neue Breite * @param height neue hoehe * @param quality neue Qualitaet (0 - 100) * @param factor Faktor fuer Schaerfe / Unschaerfe (z.B. -0.15f fuer leichte * Unschaerfe, 0.05f fuer leichtes Nachschaerfen) * @param withTransparency ob Transparenz benoetigt wird * @return neues, in Groesse und Qualitaet entsprechend verringertes Bild * @throws java.lang.InterruptedException * @throws java.io.FileNotFoundException */ public BufferedImage getReducedImage2(Image image, int width, int height, int quality, float factor, boolean withTransparency) throws InterruptedException, FileNotFoundException, IOException { int imageWidth = image.getWidth(null); int imageHeight = image.getHeight(null); int thumbWidth = width; int thumbHeight = height; if (imageWidth < width) { thumbWidth = imageWidth; } if (imageHeight < height) { thumbHeight = imageHeight; } double thumbRatio = (double) thumbWidth / (double) thumbHeight; double imageRatio = (double) imageWidth / (double) imageHeight; if(imageWidth > imageHeight) { // Querformat thumbHeight = (int) (thumbWidth / imageRatio); } else if(imageWidth == imageHeight) { // 1:1 kann so bleiben } else { // Hochformat thumbWidth = (int) (thumbHeight * imageRatio); } // draw original image to thumbnail image object and // scale it to the new size on-the-fly //BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); BufferedImage thumbImage; if (withTransparency) { thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_ARGB); } else { thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); } Graphics2D graphics2D = thumbImage.createGraphics(); graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null); // 30.7.2007: sharpening hinzugefuegt (Anfang) //float factor = -0.15f; // minus = sharpen, plus = soften //float[] sharpenArray = {0, -1, 0, -1, 5, -1, 0, -1, 0}; /* 30.6.2013: sharpening als Weichmacher nur, wenn Bild < 400 */ /*if(thumbWidth < 400 || thumbHeight < 400) { factor = 0.1f; }*/ if (factor != 0.f) { float[] array = {0, factor, 0, factor, 1 - (factor * 4), factor, 0, factor, 0}; Kernel kernel = new Kernel(3, 3, array); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); thumbImage = cOp.filter(thumbImage, null); } // 30.7.2007: sharpening hinzugefuegt (Ende) return thumbImage; } /** * Eine in Groesse und Qualitaet verringerte Bilddatei erzeugen * * @param image Ablageort und Name der Bilddatei * @param width neue Breite * @param height neue hoehe * @param quality neue Qualitaet (0 - 100) * @param factor Faktor fuer Schaerfe / Unschaerfe (z.B. -0.15f fuer leichte * Unschaerfe, 0.05f fuer leichtes Nachschaerfen) * @param withTransparency ob Transparenz benoetigt wird * @return neues, in Groesse und Qualitaet entsprechend verringertes Bild * @throws java.lang.InterruptedException * @throws java.io.FileNotFoundException */ public BufferedImage getReducedImage(Image image, int width, int height, int quality, float factor, boolean withTransparency) throws InterruptedException, FileNotFoundException, IOException { int imageWidth = image.getWidth(null); int imageHeight = image.getHeight(null); int thumbWidth = width; int thumbHeight = height; if (imageWidth < width) { thumbWidth = imageWidth; } if (imageHeight < height) { thumbHeight = imageHeight; } double thumbRatio = (double) thumbWidth / (double) thumbHeight; double imageRatio = (double) imageWidth / (double) imageHeight; if (thumbRatio < imageRatio) { thumbHeight = (int) (thumbWidth / imageRatio); } else { thumbWidth = (int) (thumbHeight * imageRatio); } // draw original image to thumbnail image object and // scale it to the new size on-the-fly //BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); BufferedImage thumbImage; if (withTransparency) { thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_ARGB); } else { thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); } Graphics2D graphics2D = thumbImage.createGraphics(); graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null); // 30.7.2007: sharpening hinzugefuegt (Anfang) //float factor = -0.15f; // minus = sharpen, plus = soften //float[] sharpenArray = {0, -1, 0, -1, 5, -1, 0, -1, 0}; /* 30.6.2013: sharpening als Weichmacher nur, wenn Bild < 400 */ /*if(thumbWidth < 400 || thumbHeight < 400) { factor = 0.1f; }*/ if (factor != 0.f) { float[] array = {0, factor, 0, factor, 1 - (factor * 4), factor, 0, factor, 0}; Kernel kernel = new Kernel(3, 3, array); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); thumbImage = cOp.filter(thumbImage, null); } // 30.7.2007: sharpening hinzugefuegt (Ende) return thumbImage; } public String imgType(String mimeType) { String imgType; if (mimeType.contains("jpg")) { imgType = "jpg"; } else if (mimeType.contains("jpeg")) { imgType = "jpg"; } else if (mimeType.contains("png")) { imgType = "png"; } else if (mimeType.contains("gif")) { imgType = "gif"; } else { imgType = "jpg"; } return imgType; } /** * * @param v Bild.WINZIG .. Bild.GROSS * @return Länge der längsten Kante in Bildpunkten */ public int getVariantenGroesse(int v) { return GR[v]; } public String getVariantenName(int v) { return GRNAME[v]; } public String getMimeType(File file) { String absName = file.getAbsolutePath(); FileNameMap fileNameMap = URLConnection.getFileNameMap(); return fileNameMap.getContentTypeFor("file://" + absName); } }