comparison src/fschmidt/util/java/ImageUtils.java @ 68:00520880ad02

add fschmidt source
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 05 Oct 2025 17:24:15 -0600
parents
children
comparison
equal deleted inserted replaced
67:9d0fefce6985 68:00520880ad02
1 /*
2 Copyright (c) 2008 Franklin Schmidt <fschmidt@gmail.com>
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22
23 package fschmidt.util.java;
24
25 import sun.awt.image.BufferedImageGraphicsConfig;
26
27 import javax.imageio.ImageIO;
28 import java.awt.AlphaComposite;
29 import java.awt.Graphics2D;
30 import java.awt.GraphicsConfiguration;
31 import java.awt.RenderingHints;
32 import java.awt.Transparency;
33 import java.awt.image.BufferedImage;
34 import java.awt.image.BufferedImageOp;
35 import java.awt.image.ConvolveOp;
36 import java.awt.image.Kernel;
37 import java.io.ByteArrayInputStream;
38 import java.io.ByteArrayOutputStream;
39 import java.io.File;
40 import java.io.FileInputStream;
41 import java.io.FileOutputStream;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.util.HashMap;
45 import java.util.Map;
46
47
48 public final class ImageUtils {
49 private ImageUtils() {} // never
50
51 public static ImageDetails saveImage(String imagePath, BufferedImage image, String format)
52 throws IllegalArgumentException, IOException
53 {
54 FileOutputStream fos = new FileOutputStream(imagePath);
55 try {
56 ImageIO.write(image, format, fos);
57 } finally {
58 image.flush();
59 fos.close();
60 }
61 return new ImageDetails(image.getHeight(), image.getWidth());
62 }
63
64 public static BufferedImage loadImage(String imagePath)
65 throws IOException, IllegalArgumentException
66 {
67 FileInputStream fis = new FileInputStream(imagePath);
68 try {
69 return createCompatibleImage(ImageIO.read(fis));
70 } finally {
71 fis.close();
72 }
73 }
74
75 public static BufferedImage getImage(InputStream in)
76 throws IOException, IllegalArgumentException
77 {
78 BufferedImage img = ImageIO.read(in);
79 return img == null? null : createCompatibleImage(img);
80 }
81
82 public static void deleteImage(String imagePath) {
83 File imageFile = new File(imagePath);
84 if (imageFile.exists())
85 imageFile.delete();
86 }
87
88 private static BufferedImage fixImage(BufferedImage img) {
89 // Clone the image using the RGB type to prevent color problems.
90 BufferedImage temp = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
91 Graphics2D g2 = temp.createGraphics();
92 g2.drawImage(img, 0, 0, null);
93 g2.dispose();
94 return temp;
95 }
96
97 public static ByteArrayOutputStream asOutputStream(BufferedImage img, String format) throws IOException {
98 ByteArrayOutputStream baos = new ByteArrayOutputStream();
99 ImageIO.write(fixImage(img), format, baos);
100 return baos;
101 }
102
103 public static InputStream asInputStream(BufferedImage img, String format) throws IOException {
104 ByteArrayOutputStream baos = asOutputStream(img, format);
105 final byte[] bytes = baos.toByteArray();
106 return new ByteArrayInputStream(bytes);
107 }
108
109 public static BufferedImage cropImage(BufferedImage image, int x, int y, int width, int height)
110 throws IllegalArgumentException, IOException
111 {
112 if (x < 0) x = 0;
113 if (y < 0) y = 0;
114 if (width > image.getWidth())
115 width = image.getWidth();
116 if (height > image.getHeight())
117 height = image.getHeight();
118 if (x + width > image.getWidth())
119 x = image.getWidth() - width;
120 if (y + height > image.getHeight())
121 y = image.getHeight() - height;
122 return image.getSubimage(x, y, width, height);
123 }
124
125 public static BufferedImage resizeImage(BufferedImage image, int width, int height) {
126 int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
127 BufferedImage resizedImage = new BufferedImage(width, height, type);
128 Graphics2D g = resizedImage.createGraphics();
129 g.setComposite(AlphaComposite.Src);
130 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
131 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
132 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
133 g.drawImage(image, 0, 0, width, height, null);
134 g.dispose();
135 return resizedImage;
136 }
137
138 public static BufferedImage resizeKeepRatio(BufferedImage img, int width, int height) {
139 int newWidth = img.getWidth() < img.getHeight()? (int) Math.ceil(img.getWidth() * height / (float) img.getHeight()) : width;
140 int newHeight = img.getWidth() < img.getHeight()? height : (int) Math.ceil(img.getHeight() * width / (float) img.getWidth());
141 if (newWidth > width) {
142 newWidth = width;
143 newHeight = img.getHeight() * width / img.getWidth();
144 } else if (newHeight > height) {
145 newWidth = img.getWidth() * height / img.getHeight();
146 newHeight = height;
147 }
148 return resizeImage(img, newWidth, newHeight);
149 }
150
151 public static BufferedImage blurImage(BufferedImage image) {
152 float ninth = 1.0f/9.0f;
153 float[] blurKernel = {
154 ninth, ninth, ninth,
155 ninth, ninth, ninth,
156 ninth, ninth, ninth
157 };
158
159 Map<RenderingHints.Key, Object> map = new HashMap<RenderingHints.Key, Object>();
160 map.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
161 map.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
162 map.put(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
163 RenderingHints hints = new RenderingHints(map);
164 BufferedImageOp op = new ConvolveOp(new Kernel(3, 3, blurKernel), ConvolveOp.EDGE_NO_OP, hints);
165 image = fixImage(image);
166 return op.filter(image, null);
167 }
168
169 private static BufferedImage createCompatibleImage(BufferedImage image) {
170 GraphicsConfiguration gc = BufferedImageGraphicsConfig.getConfig(image);
171 int w = image.getWidth();
172 int h = image.getHeight();
173 BufferedImage result = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
174 Graphics2D g2 = result.createGraphics();
175 g2.drawRenderedImage(image, null);
176 g2.dispose();
177 return result;
178 }
179
180 public static BufferedImage getThumbnail(BufferedImage img, int width, int height) {
181 if (img.getWidth() <= width && img.getHeight() <= height)
182 return img;
183 else {
184 int widthLimit = 3 * width;
185 int heightLimit = 3 * height;
186 if (img.getWidth() > widthLimit || img.getHeight() > heightLimit) {
187 img = resizeKeepRatio(img, widthLimit, heightLimit);
188 img = blurImage(img);
189 }
190 return resizeKeepRatio(img, width, height);
191 }
192 }
193
194 public static final class ImageDetails {
195 private int height;
196 private int width;
197
198 public ImageDetails(int height, int width) {
199 this.height = height;
200 this.width = width;
201 }
202
203 public int getHeight() { return height; }
204 public int getWidth() { return width; }
205 }
206
207 /* public static void main(String[] args) {
208 // 140 x 100 px
209 try {
210 testThumbnail("a.png", "a1");
211 testThumbnail("b.jpg", "b1");
212 testThumbnail("c.png", "c1");
213 testThumbnail("d.jpg", "d1");
214 testThumbnail("e.jpg", "e1");
215 testThumbnail("f.jpg", "f1");
216 testThumbnail("g.png", "g1");
217 } catch (IOException e) {
218 e.printStackTrace();
219 }
220 }
221
222 private static void testThumbnail(String fileIn, String fileOut) throws IOException {
223 String format = "jpeg";
224 BufferedImage img = loadImage("c:\\" + fileIn);
225 System.out.println(fileIn + " w:" + img.getWidth() + " h:" + img.getHeight());
226 long start = System.currentTimeMillis();
227 BufferedImage thumb = getThumbnail(img, 140, 100);
228
229 BufferedImage temp = new BufferedImage(thumb.getWidth(), thumb.getHeight(), BufferedImage.TYPE_INT_RGB);
230 Graphics2D g2 = temp.createGraphics();
231 g2.drawImage(thumb, 0, 0, null);
232 g2.dispose();
233 thumb = temp;
234
235 System.out.println("Time = " + (System.currentTimeMillis()-start));
236 saveImage("c:\\"+fileOut+'.'+format, thumb, format);
237 }*/
238 }