前面有一篇已经介绍tesseract-OCR的简单实用和识别,因识别率不高,特意将图片实用opencv处理后,再次进行识别,经过测试,识别率高了30%左右
2,实用opcv整合tesseract-OCR需要的jar包,此处的识别已经不再通过调用windows系统命令,而通过tesseract-OCR工具类tess4j.jar完成。(实际上tess4j也是调用系统命令)
3,注意到上面有个opencv_java320.dll(32位和64位,根据你的jdk决定,到时我发现在这儿其实好像加载不到,所以使用一下方法)
将opencv_java320.dll加入到系统库的Native library location(如图)
4,上代码,学过java的一看就明白
1. package com.njupt.zhb.test;
2.
3. import java.io.BufferedReader;
4. import java.io.File;
5. import java.io.FileInputStream;
6. import java.io.InputStreamReader;
7. import java.util.ArrayList;
8. import java.util.List;
9.
10. import net.sourceforge.tess4j.Tesseract;
11. import net.sourceforge.tess4j.TesseractException;
12.
13. /**
14. * @author zwp
15. * @date 创建时间:2017年3月24日 下午5:12:12
16. * @version 2.0
17. * @parameter
18. * @since
19. * @return
20. */
21. public class Test {
22.
23. public static String test(String path) {
24. new File(path);
25.
26. Tesseract instance=Tesseract.getInstance();
27. "C:\\Program Files (x86)\\Tesseract-OCR\\tessdata");//设置训练库的位置
28. //instance.setLanguage("chi_sim");//中文识别
29. "eng");//中文识别
30. try {
31. String result = instance.doOCR(imageFile);
32. System.out.println(result);
33. return result;
34. catch (TesseractException e) {
35. e.printStackTrace();
36. }
37. return "";
38. }
39.
40. private final String LANG_OPTION = "-l";
41. private final String EOL = System.getProperty("line.separator");
42. /**
43. * 文件位置我防止在,项目同一路径
44. */
45. private String tessPath = new File("tesseract").getAbsolutePath();
46.
47. /**
48. * @param imageFile
49. * 传入的图像文件
50. * @param imageFormat
51. * 传入的图像格式
52. * @return 识别后的字符串
53. */
54. public String recognizeText(File imageFile) throws Exception
55. {
56. /**
57. * 设置输出文件的保存的文件目录
58. */
59. new File(imageFile.getParentFile(), "output");
60.
61. new StringBuffer();
62. new ArrayList<String>();
63.
64. "os.name");
65. if(os.toLowerCase().startsWith("win")){
66. "tesseract");
67. else {
68. "tesseract");
69. }
70. // cmd.add(tessPath + "\\tesseract");
71. cmd.add(imageFile.getName());
72. cmd.add(outputFile.getName());
73. // cmd.add(LANG_OPTION);
74. // cmd.add("chi_sim");
75. "digits");
76. // cmd.add("eng");
77. // cmd.add("-psm 7");
78. new ProcessBuilder();
79.
80. /**
81. *Sets this process builder's working directory.
82. */
83. pb.directory(imageFile.getParentFile());
84. // cmd.set(1, imageFile.getName());
85. pb.command(cmd);
86. true);
87. Process process = pb.start();
88.
89. // Process process = pb.command("ipconfig").start();
90. // System.out.println(System.getenv().get("Path"));
91. // Process process = pb.command("D:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe",imageFile.getName(),outputFile.getName(),LANG_OPTION,"eng").start();
92.
93. // tesseract.exe 1.jpg 1 -l chi_sim
94. // Runtime.getRuntime().exec("tesseract.exe 1.jpg 1 -l chi_sim");
95. /**
96. * the exit value of the process. By convention, 0 indicates normal
97. * termination.
98. */
99. // System.out.println(cmd.toString());
100. int w = process.waitFor();
101. if (w == 0)// 0代表正常退出
102. {
103. new BufferedReader(new InputStreamReader(
104. new FileInputStream(outputFile.getAbsolutePath() + ".txt"),
105. "UTF-8"));
106. String str;
107.
108. while ((str = in.readLine()) != null)
109. {
110. strB.append(str).append(EOL);
111. }
112. in.close();
113. else
114. {
115. String msg;
116. switch (w)
117. {
118. case 1:
119. "Errors accessing files. There may be spaces in your image's filename.";
120. break;
121. case 29:
122. "Cannot recognize the image or its selected region.";
123. break;
124. case 31:
125. "Unsupported image format.";
126. break;
127. default:
128. "Errors occurred.";
129. }
130. throw new RuntimeException(msg);
131. }
132. new File(outputFile.getAbsolutePath() + ".txt").delete();
133. return strB.toString().replaceAll("\\s*", "");
134. }
135. /*public static void main(String[] args) throws Exception {
136. Tesseract("d:\\2.png");
137. Tesseract("/2.png");
138. Tesseract("/3.png");
139. Tesseract("/4.png");
140. Tesseract("/5.png");
141. Tesseract("/6.png");
142. }
143. */
144. private static void Tesseract(String fileString) throws Exception {
145. // String filePath = Test.class.getResource(fileString).getFile().toString();
146. // processImg(filePath);
147. new File(fileString);
148. new Test().recognizeText(file);
149. System.out.println(recognizeText);
150. }
151. }
1. package com.njupt.zhb.test;
2.
3. import java.awt.Image;
4. import java.awt.color.ColorSpace;
5. import java.awt.image.BufferedImage;
6. import java.awt.image.ColorConvertOp;
7. import java.io.File;
8. import java.io.FileInputStream;
9. import java.io.FileNotFoundException;
10. import java.io.FileOutputStream;
11. import java.io.IOException;
12. import java.io.OutputStream;
13. import java.util.Arrays;
14.
15. import javax.imageio.ImageIO;
16. import javax.imageio.ImageReadParam;
17. import javax.imageio.ImageReader;
18. import javax.imageio.stream.FileImageInputStream;
19. import javax.imageio.stream.ImageInputStream;
20.
21. import org.opencv.core.Mat;
22. import org.opencv.core.MatOfRect;
23. import org.opencv.core.Rect;
24. import org.opencv.core.Size;
25. import org.opencv.imgcodecs.Imgcodecs;
26. import org.opencv.objdetect.CascadeClassifier;
27.
28.
29. public class Main {
30. private static final Double avatarSpacePer = 0.16;
31. private static final Double avatarPer = 0.28;
32.
33. /**
34. * @param args
35. */
36. public static void main(String[] args) {
37. // TODO Auto-generated method stub
38. /*
39. * System.loadLibrary("opencv_java320"); Mat m = Mat.eye(3, 3,
40. * CvType.CV_8UC1); System.out.println("m = " + m.dump());
41. */
42. "opencv_java320");
43. /*
44. * Mat mat = Imgcodecs.imread("d:/data/1.jpg"); System.out.println(mat);
45. */
46. new File("d:/data");
47. if (file.isDirectory()) {
48. File[] files = file.listFiles();
49. for (File f : files) {
50. test(f.getPath());
51. }
52. }
53. // test("d:/data/1.png");
54. }
55.
56. private static void test(String fileName) {
57. int index = fileName.lastIndexOf("\\");
58. 1 ? fileName.substring(index + 1) : ".png";
59. int[] rectPosition = detectFace(fileName);
60. "x=" + rectPosition[0] + " y=" + rectPosition[1] + " width=" + rectPosition[2] + " height="
61. 3]);
62.
63. int x = rectPosition[0];
64. int y = rectPosition[1];
65. int w = rectPosition[2];
66. int h = rectPosition[3];
67. int[] imgRect = new int[2];
68. try {
69. imgRect = getImageWidth(fileName);
70. catch (FileNotFoundException e) {
71. e.printStackTrace();
72. catch (IOException e) {
73. e.printStackTrace();
74. }
75. /*
76. * if(x == 0 || y == 0 || w == 0 || h == 0 ){
77. * System.out.println("人脸识别失败:" + fileName + " 把身份证变成黑白照片再次进行识别");
78. * String destFile = "d:/data/temp" + suffix;
79. * //convertBackWhiteImage(fileName, destFile); changeImge(new
80. * File(fileName)); rectPosition = detectFace(fileName); // rectPosition
81. * = detectFace(destFile); System.out.println("x=" + rectPosition[0] +
82. * " y=" + rectPosition[1] + " width=" + rectPosition[2] + " height=" +
83. * rectPosition[3]);
84. *
85. * x = rectPosition[0]; y = rectPosition[1]; w = rectPosition[2]; h =
86. * rectPosition[3]; }
87. */
88. if (x == 0 || y == 0 || w == 0 || h == 0) {
89.
90. 0];
91. 1];
92. int) (x * avatarPer);
93. h = w;
94. "人脸识别失败:" + fileName + " 采用默认识别");
95.
96. }
97. /*
98. * int cutX = x/4 + 20; int cutY = (y + h ) *2;
99. */
100. int cutX = x / 2 - 20;
101.
102. "d:/data/idcard" + suffix;
103.
104. int width = imgRect[0] - cutX - 30;
105. // ImageUtils.cut(fileName, destFile, cutX, cutY, width/2, 120);
106. // ImageUtils.cut(fileName, "d:/data/avatar.jpg", x, y, w, h);
107. int cutHeight = 140;
108. int imgHieght = imgRect[1];
109. int topSpace = (int) (imgHieght * avatarPer);
110. int height = (int) (imgHieght * avatarSpacePer);
111. int cutY = y + h + height;
112. if (imgHieght - cutY < cutHeight - 5) {
113. int) (imgHieght / 3.8) - 10;
114. }
115. if (imgHieght < 500) {
116. 20;
117. }
118. new Main().cutImage(fileName, destFile, cutX, cutY, width, cutHeight);
119. Test.test(destFile);
120. }
121.
122.
123. /**
124. * 图片转换成黑白图片
125. *
126. * @param fileName
127. * @param destFile
128. */
129. public static void convertBackWhiteImage(String fileName, String destFile) {
130. null;
131. null;
132. "]", ",");
133. // 获取图片后缀
134. if (fileName.indexOf(".") > -1) {
135. ".") + 1);
136. // 类型和图片后缀全部小写,然后判断后缀是否合法
137. if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase() + ",") < 0) {
138. return;
139. }
140. try {
141. new FileInputStream(fileName)));
142. new FileOutputStream(destFile);
143. ImageIO.write(sourceImg, suffix, output);
144. catch (FileNotFoundException e) {
145. // TODO Auto-generated catch block
146. e.printStackTrace();
147. catch (IOException e) {
148. // TODO Auto-generated catch block
149. e.printStackTrace();
150. finally {
151. if (output != null)
152. try {
153. output.close();
154. catch (IOException e) {
155. // TODO Auto-generated catch block
156. e.printStackTrace();
157. }
158. }
159. }
160.
161. /**
162. * 把图像处理成黑白照片
163. *
164. * @param bi
165. * @return
166. */
167. public static BufferedImage replaceWithWhiteColor(BufferedImage bi) {
168.
169. int[] rgb = new int[3];
170.
171. int width = bi.getWidth();
172.
173. int height = bi.getHeight();
174.
175. int minx = bi.getMinX();
176.
177. int miny = bi.getMinY();
178.
179. /**
180. *
181. * 遍历图片的像素,为处理图片上的杂色,所以要把指定像素上的颜色换成目标白色 用二层循环遍历长和宽上的每个像素
182. *
183. */
184.
185. int hitCount = 0;
186.
187. for (int i = minx; i < width - 1; i++) {
188.
189. for (int j = miny; j < height; j++) {
190.
191. /**
192. *
193. * 得到指定像素(i,j)上的RGB值,
194. *
195. */
196.
197. int pixel = bi.getRGB(i, j);
198.
199. int pixelNext = bi.getRGB(i + 1, j);
200.
201. /**
202. *
203. * 分别进行位操作得到 r g b上的值
204. *
205. */
206.
207. 0] = (pixel & 0xff0000) >> 16;
208.
209. 1] = (pixel & 0xff00) >> 8;
210.
211. 2] = (pixel & 0xff);
212.
213. /**
214. *
215. * 进行换色操作,我这里是要换成白底,那么就判断图片中rgb值是否在范围内的像素
216. *
217. */
218.
219. // 经过不断尝试,RGB数值相互间相差15以内的都基本上是灰色,
220.
221. // 对以身份证来说特别是介于73到78之间,还有大于100的部分RGB值都是干扰色,将它们一次性转变成白色
222.
223. if ((Math.abs(rgb[0] - rgb[1]) < 15)
224.
225. 0] - rgb[2]) < 15)
226.
227. 1] - rgb[2]) < 15) &&
228.
229. 0] > 73) && (rgb[0] < 78)) || (rgb[0] > 100))) {
230.
231. // 进行换色操作,0xffffff是白色
232.
233. 0xffffff);
234.
235. }
236.
237. }
238.
239. }
240.
241. return bi;
242.
243. }
244.
245. public static int[] getImageWidth(String fileName) throws FileNotFoundException, IOException {
246. new File(fileName);
247. new FileInputStream(picture));
248. int[] imgRect = new int[2];
249. 0] = sourceImg.getWidth();
250. 1] = sourceImg.getHeight();
251. return imgRect;
252. }
253.
254. public static int[] detectFace(String fileName) {
255. int[] rectPosition = new int[4];
256. new CascadeClassifier("./data/lbpcascade_frontalface.xml");
257. Mat image = Imgcodecs.imread(fileName);
258. new MatOfRect();
259. new Size(120, 120);
260.
261. new Size(250, 250);
262. 1.1f, 4, 0, minSize, maxSize);
263.
264. "Detected %s faces", faceDetections.toArray().length));
265. for (Rect rect : faceDetections.toArray()) {
266. System.out.println(rect.toString());
267. 0] = rect.x;
268. 1] = rect.y;
269. 2] = rect.width;
270. 3] = rect.height;
271. }
272.
273. /*
274. * String filename = "d:/data/avatar.jpg";
275. * System.out.println(String.format("Writing %s", filename));
276. * Imgcodecs.imwrite(filename, image);
277. */
278. return rectPosition;
279. }
280.
281. /**
282. * <p>
283. * Title: cutImage
284. * </p>
285. * <p>
286. * Description: 根据原图与裁切size截取局部图片
287. * </p>
288. *
289. * @param srcImg
290. * 源图片
291. * @param output
292. * 图片输出流
293. * @param rect
294. * 需要截取部分的坐标和大小
295. */
296. public void cutImage(File srcImg, File destImg, java.awt.Rectangle rect) {
297. if (srcImg.exists()) {
298. null;
299. null;
300. null;
301. try {
302. new FileInputStream(srcImg);
303. // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG,
304. // JPEG, WBMP, GIF, gif]
305. "]", ",");
306. null;
307. // 获取图片后缀
308. if (srcImg.getName().indexOf(".") > -1) {
309. ".") + 1);
310. // 类型和图片后缀全部小写,然后判断后缀是否合法
311. if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase() + ",") < 0) {
312. return;
313. }
314. // 将FileInputStream 转换为ImageInputStream
315. iis = ImageIO.createImageInputStream(fis);
316. // 根据图片类型获取该种类型的ImageReader
317. new FileImageInputStream(srcImg)).next(); // ImageIO.getImageReadersBySuffix(suffix).next();
318. true);
319. ImageReadParam param = reader.getDefaultReadParam();
320. param.setSourceRegion(rect);
321. 0, param);
322. new FileOutputStream(destImg);
323. ImageIO.write(bi, suffix, output);
324. catch (FileNotFoundException e) {
325. e.printStackTrace();
326. catch (IOException e) {
327. e.printStackTrace();
328. finally {
329. try {
330. if (fis != null)
331. fis.close();
332. if (iis != null)
333. iis.close();
334. if (output != null)
335. output.close();
336. catch (IOException e) {
337. e.printStackTrace();
338. }
339. }
340. else {
341. }
342. }
343.
344. public void cutImage(String srcImg, String destImg, int x, int y, int width, int height) {
345. new File(srcImg), new File(destImg), new java.awt.Rectangle(x, y, width, height));
346. }
347.
348. }
1. package com.njupt.zhb.test.util;
2.
3. import java.awt.AlphaComposite;
4. import java.awt.Color;
5. import java.awt.Font;
6. import java.awt.Graphics;
7. import java.awt.Graphics2D;
8. import java.awt.Image;
9. import java.awt.Toolkit;
10. import java.awt.color.ColorSpace;
11. import java.awt.geom.AffineTransform;
12. import java.awt.image.AffineTransformOp;
13. import java.awt.image.BufferedImage;
14. import java.awt.image.ColorConvertOp;
15. import java.awt.image.CropImageFilter;
16. import java.awt.image.FilteredImageSource;
17. import java.awt.image.ImageFilter;
18. import java.io.File;
19. import java.io.FileInputStream;
20. import java.io.FileOutputStream;
21. import java.io.IOException;
22. import java.util.logging.Logger;
23.
24. import javax.imageio.ImageIO;
25.
26. import org.apache.commons.io.IOUtils;
27. import org.apache.commons.lang3.StringUtils;
28.
29. import com.alibaba.simpleimage.ImageRender;
30. import com.alibaba.simpleimage.SimpleImageException;
31. import com.alibaba.simpleimage.render.ReadRender;
32. import com.alibaba.simpleimage.render.ScaleParameter;
33. import com.alibaba.simpleimage.render.ScaleRender;
34. import com.alibaba.simpleimage.render.WriteRender;
35.
36. /**
37. * 图片处理工具类:<br>
38. * 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
39. *
40. */
41. public class ImageUtils {
42. // 缩略图宽度
43. public static int SMALL_IMG_WIDTH = 240;
44. // 缩略图高度
45. public static int SMALL_IMG_HEIGHT = 240;
46. static {
47. "com.sun.media.jai.disableMediaLib", "true");
48. }
49.
50.
51. /**
52. * 几种常见的图片格式
53. */
54. public static String IMAGE_TYPE_GIF = "gif";// 图形交换格式
55. public static String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组
56. public static String IMAGE_TYPE_JPEG = "jpeg";// 联合照片专家组
57. public static String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式
58. public static String IMAGE_TYPE_PNG = "png";// 可移植网络图形
59. public static String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop
60.
61. /**
62. * 检查图片类型
63. *
64. * @param fileFileName2
65. * @return
66. *
67. */
68. public static boolean checkType(String fileFileName) {
69. if (StringUtils.isBlank(fileFileName)) {
70. return false;
71. }
72. fileFileName = fileFileName.toLowerCase();
73. if ((!fileFileName.endsWith(IMAGE_TYPE_GIF) && !fileFileName.endsWith(IMAGE_TYPE_JPG)
74. && !fileFileName.endsWith(IMAGE_TYPE_JPEG) && !fileFileName.endsWith(IMAGE_TYPE_BMP)
75. && !fileFileName.endsWith(IMAGE_TYPE_PNG) && !fileFileName.endsWith(IMAGE_TYPE_PSD))) {
76. return false;
77. }
78. return true;
79. }
80.
81. /**
82. * 程序入口:用于测试
83. *
84. * @param args
85. */
86. public static void main2(String[] args) {
87. // 1-缩放图像:
88. // 方法一:按比例缩放
89. "e:/abc.jpg", "e:/abc_scale.jpg", 2, true);// 测试OK
90. // 方法二:按高度和宽度缩放
91. "e:/abc.jpg", "e:/abc_scale2.jpg", 500, 300, true);// 测试OK
92.
93. // 2-切割图像:
94. // 方法一:按指定起点坐标和宽高切割
95. "e:/abc.jpg", "e:/abc_cut.jpg", 0, 0, 400, 400);// 测试OK
96. // 方法二:指定切片的行数和列数
97. "e:/abc.jpg", "e:/", 2, 2);// 测试OK
98. // 方法三:指定切片的宽度和高度
99. "e:/abc.jpg", "e:/", 300, 300);// 测试OK
100.
101. // 3-图像类型转换:
102. "e:/abc.jpg", "GIF", "e:/abc_convert.gif");// 测试OK
103.
104. // 4-彩色转黑白:
105. "e:/abc.jpg", "e:/abc_gray.jpg");// 测试OK
106.
107. // 5-给图片添加文字水印:
108. // 方法一:
109. "我是水印文字", "e:/abc.jpg", "e:/abc_pressText.jpg", "宋体", Font.BOLD, Color.white, 80, 0, 0,
110. 0.5f);// 测试OK
111. // 方法二:
112. "我也是水印文字", "e:/abc.jpg", "e:/abc_pressText2.jpg", "黑体", 36, Color.white, 80, 0, 0, 0.5f);// 测试OK
113.
114. // 6-给图片添加图片水印:
115. "e:/abc2.jpg", "e:/abc.jpg", "e:/abc_pressImage.jpg", 0, 0, 0.5f);// 测试OK
116. }
117.
118. /**
119. * 缩放图像(按比例缩放)
120. *
121. * @param srcImageFile
122. * 源图像文件地址
123. * @param result
124. * 缩放后的图像地址
125. * @param scale
126. * 缩放比例
127. * @param flag
128. * 缩放选择:true 放大; false 缩小;
129. */
130. public final static void scale(String srcImageFile, String result, int scale, boolean flag) {
131. try {
132. synchronized (ImageUtils.class) {
133. new File(srcImageFile)); // 读入文件
134. int width = src.getWidth(); // 得到源图宽
135. int height = src.getHeight(); // 得到源图长
136. if (flag) {// 放大
137. width = width * scale;
138. height = height * scale;
139. else {// 缩小
140. int wScale = width / SMALL_IMG_WIDTH;
141. int hScale = height / SMALL_IMG_HEIGHT;
142. scale = wScale > hScale ? hScale : wScale;
143. 1 ? 1 : scale;
144. width = width / scale;
145. height = height / scale;
146. }
147. Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT);
148. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
149. Graphics g = tag.getGraphics();
150. 0, 0, null); // 绘制缩小后的图
151. g.dispose();
152. "JPEG", new File(result));// 输出到文件流
153. }
154. catch (IOException e) {
155. e.printStackTrace();
156. }
157. }
158.
159. /**
160. * 缩放图像(按比例缩放)
161. *
162. * @param srcImageFile
163. * 源图像文件地址
164. * @param result
165. * 缩放后的图像地址
166. * @param scale
167. * 缩放比例
168. * @param flag
169. * 缩放选择:true 放大; false 缩小;
170. */
171. public final static void scale(String srcImageFile, String result, int scale, boolean flag, int wd, int he) {
172. try {
173. synchronized (ImageUtils.class) {
174. new File(srcImageFile)); // 读入文件
175. int width = src.getWidth(); // 得到源图宽
176. int height = src.getHeight(); // 得到源图长
177. if (flag) {// 放大
178. width = width * scale;
179. height = height * scale;
180. else {// 缩小
181. int wScale = width / wd;
182. int hScale = height / he;
183. scale = wScale > hScale ? hScale : wScale;
184. 1 ? 1 : scale;
185. width = width / scale;
186. height = height / scale;
187. }
188. Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT);
189. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
190. Graphics g = tag.getGraphics();
191. 0, 0, null); // 绘制缩小后的图
192. g.dispose();
193. "JPEG", new File(result));// 输出到文件流
194. }
195. catch (IOException e) {
196. e.printStackTrace();
197. }
198. }
199.
200. /**
201. * 缩放图像(按比例缩放)
202. *
203. * @param srcImageFile
204. * 源图像文件地址
205. * @param result
206. * 缩放后的图像地址
207. * @param scale
208. * 缩放比例t
209. * @param flag
210. * 缩放选择:true 放大; false 缩小;
211. */
212. public final static void scaleByHeightAndWidth(int hightVal, int widthVal, String srcImageFile, String result, int scale, boolean flag) {
213. try {
214. synchronized (ImageUtils.class) {
215. new File(srcImageFile)); // 读入文件
216. int width = src.getWidth(); // 得到源图宽
217. int height = src.getHeight(); // 得到源图长
218. if (flag) {// 放大
219. width = width * scale;
220. height = height * scale;
221. else {// 缩小
222. int wScale = width / widthVal;
223. int hScale = height / hightVal;
224. scale = wScale > hScale ? hScale : wScale;
225. 1 ? 1 : scale;
226. width = width / scale;
227. height = height / scale;
228. }
229. Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT);
230. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
231. Graphics g = tag.getGraphics();
232. 0, 0, null); // 绘制缩小后的图
233. g.dispose();
234. "JPEG", new File(result));// 输出到文件流
235. }
236. catch (IOException e) {
237. e.printStackTrace();
238. }
239. }
240.
241. /**
242. * 缩放图像(按高度和宽度缩放)
243. *
244. * @param srcImageFile
245. * 源图像文件地址
246. * @param result
247. * 缩放后的图像地址
248. * @param height
249. * 缩放后的高度
250. * @param width
251. * 缩放后的宽度
252. * @param bb
253. * 比例不对时是否需要补白:true为补白; false为不补白;
254. */
255. @SuppressWarnings("static-access")
256. @Deprecated
257. public final static void scale2(String srcImageFile, String result, int height, int width, boolean bb) {
258. try {
259. double ratio = 0.0; // 缩放比例
260. new File(srcImageFile);
261. BufferedImage bi = ImageIO.read(f);
262. Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);
263. // 计算比例
264. if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
265. if (bi.getHeight() > bi.getWidth()) {
266. new Integer(height)).doubleValue() / bi.getHeight();
267. else {
268. new Integer(width)).doubleValue() / bi.getWidth();
269. }
270. new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
271. null);
272. }
273. if (bb) {// 补白
274. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
275. Graphics2D g = image.createGraphics();
276. g.setColor(Color.white);
277. 0, 0, width, height);
278. if (width == itemp.getWidth(null))
279. 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null),
280. null), Color.white, null);
281. else
282. null)) / 2, 0, itemp.getWidth(null),
283. null), Color.white, null);
284. g.dispose();
285. itemp = image;
286. }
287. "JPEG", new File(result));
288. catch (IOException e) {
289. e.printStackTrace();
290. }
291. }
292.
293. /**
294. * 缩放图像(按高度和宽度缩放)不裁剪
295. *
296. * @param srcImageFile
297. * 源图像文件地址
298. * @param result
299. * 缩放后的图像地址
300. * @param height
301. * 缩放后的高度
302. * @param width
303. * 缩放后的宽度
304. * @param bb
305. * 比例不对时是否需要补白:true为补白; false为不补白;
306. */
307. @SuppressWarnings("static-access")
308. @Deprecated
309. public final static void scaleWithoutCut(String srcImageFile, String result, int height, int width, boolean bb) {
310. try {
311. new File(srcImageFile);
312. BufferedImage bi = ImageIO.read(f);
313. int width1 = bi.getWidth(); // 得到源图宽
314. int height1 = bi.getHeight(); // 得到源图长
315. // 创建此图像的缩放版本。返回一个新的
316. // Image
317. // 对象,默认情况下,该对象按指定的
318. // width
319. // 和
320. // height
321. // 呈现图像。即使已经完全加载了初始源图像,新的
322. // Image
323. // 对象也可以被异步加载。
324. new AffineTransformOp(
325. null);
326. null);
327. "JPEG", new File(result));
328. catch (IOException e) {
329. e.printStackTrace();
330. }
331. }
332.
333. /**
334. * 图像切割(按指定起点坐标和宽高切割)
335. *
336. * @param srcImageFile
337. * 源图像地址
338. * @param result
339. * 切片后的图像地址
340. * @param x
341. * 目标切片起点坐标X
342. * @param y
343. * 目标切片起点坐标Y
344. * @param width
345. * 目标切片宽度
346. * @param height
347. * 目标切片高度
348. */
349. public final static void cut(String srcImageFile, String result, int x, int y, int width, int height) {
350. try {
351. // 读取源图像
352. new File(srcImageFile));
353. int srcWidth = bi.getHeight(); // 源图宽度
354. int srcHeight = bi.getWidth(); // 源图高度
355. if (srcWidth > 0 && srcHeight > 0) {
356. Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
357. // 四个参数分别为图像起点坐标和宽高
358. // 即: CropImageFilter(int x,int y,int width,int height)
359. new CropImageFilter(x, y, width, height);
360. Image img = Toolkit.getDefaultToolkit()
361. new FilteredImageSource(image.getSource(), cropFilter));
362. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
363. Graphics g = tag.getGraphics();
364. 0, 0, width, height, null); // 绘制切割后的图
365. g.dispose();
366. // 输出为文件
367. "JPEG", new File(result));
368. }
369. catch (Exception e) {
370. e.printStackTrace();
371. }
372. }
373.
374. /**
375. * 图像切割(按指定起点坐标和宽高切割)无压缩
376. *
377. * @param srcImageFile
378. * 源图像地址
379. * @param result
380. * 切片后的图像地址
381. * @param x
382. * 目标切片起点坐标X
383. * @param y
384. * 目标切片起点坐标Y
385. * @param width
386. * 目标切片宽度
387. * @param height
388. * 目标切片高度
389. */
390. public final static void cutWithoutScale(String srcImageFile, String result, int x, int y, int width, int height) {
391. try {
392. // 读取源图像
393. new File(srcImageFile));
394. int srcWidth = bi.getHeight(); // 源图宽度
395. int srcHeight = bi.getWidth(); // 源图高度
396. if (srcWidth > 0 && srcHeight > 0) {
397. Image image = bi.getSubimage(x, y, width, height);
398. // 四个参数分别为图像起点坐标和宽高
399. // 即: CropImageFilter(int x,int y,int width,int height)
400. new CropImageFilter(x, y, width, height);
401. Image img = Toolkit.getDefaultToolkit()
402. new FilteredImageSource(image.getSource(), cropFilter));
403. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
404. Graphics g = tag.getGraphics();
405. 0, 0, width, height, null); // 绘制切割后的图
406. g.dispose();
407. // 输出为文件
408. "JPEG", new File(result));
409. }
410. catch (Exception e) {
411. e.printStackTrace();
412. }
413. }
414.
415. /**
416. * 图像切割(指定切片的行数和列数)
417. *
418. * @param srcImageFile
419. * 源图像地址
420. * @param descDir
421. * 切片目标文件夹
422. * @param rows
423. * 目标切片行数。默认2,必须是范围 [1, 20] 之内
424. * @param cols
425. * 目标切片列数。默认2,必须是范围 [1, 20] 之内
426. */
427. public final static void cut2(String srcImageFile, String descDir, int rows, int cols) {
428. try {
429. if (rows <= 0 || rows > 20)
430. 2; // 切片行数
431. if (cols <= 0 || cols > 20)
432. 2; // 切片列数
433. // 读取源图像
434. new File(srcImageFile));
435. int srcWidth = bi.getHeight(); // 源图宽度
436. int srcHeight = bi.getWidth(); // 源图高度
437. if (srcWidth > 0 && srcHeight > 0) {
438. Image img;
439. ImageFilter cropFilter;
440. Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
441. int destWidth = srcWidth; // 每张切片的宽度
442. int destHeight = srcHeight; // 每张切片的高度
443. // 计算切片的宽度和高度
444. if (srcWidth % cols == 0) {
445. destWidth = srcWidth / cols;
446. else {
447. int) Math.floor(srcWidth / cols) + 1;
448. }
449. if (srcHeight % rows == 0) {
450. destHeight = srcHeight / rows;
451. else {
452. int) Math.floor(srcWidth / rows) + 1;
453. }
454. // 循环建立切片
455. // 改进的想法:是否可用多线程加快切割速度
456. for (int i = 0; i < rows; i++) {
457. for (int j = 0; j < cols; j++) {
458. // 四个参数分别为图像起点坐标和宽高
459. // 即: CropImageFilter(int x,int y,int width,int height)
460. new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight);
461. img = Toolkit.getDefaultToolkit()
462. new FilteredImageSource(image.getSource(), cropFilter));
463. new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
464. Graphics g = tag.getGraphics();
465. 0, 0, null); // 绘制缩小后的图
466. g.dispose();
467. // 输出为文件
468. "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg"));
469. }
470. }
471. }
472. catch (Exception e) {
473. e.printStackTrace();
474. }
475. }
476.
477. /**
478. * 图像切割(指定切片的宽度和高度)
479. *
480. * @param srcImageFile
481. * 源图像地址
482. * @param descDir
483. * 切片目标文件夹
484. * @param destWidth
485. * 目标切片宽度。默认200
486. * @param destHeight
487. * 目标切片高度。默认150
488. */
489. public final static void cut3(String srcImageFile, String descDir, int destWidth, int destHeight) {
490. try {
491. if (destWidth <= 0)
492. 200; // 切片宽度
493. if (destHeight <= 0)
494. 150; // 切片高度
495. // 读取源图像
496. new File(srcImageFile));
497. int srcWidth = bi.getHeight(); // 源图宽度
498. int srcHeight = bi.getWidth(); // 源图高度
499. if (srcWidth > destWidth && srcHeight > destHeight) {
500. Image img;
501. ImageFilter cropFilter;
502. Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
503. int cols = 0; // 切片横向数量
504. int rows = 0; // 切片纵向数量
505. // 计算切片的横向和纵向数量
506. if (srcWidth % destWidth == 0) {
507. cols = srcWidth / destWidth;
508. else {
509. int) Math.floor(srcWidth / destWidth) + 1;
510. }
511. if (srcHeight % destHeight == 0) {
512. rows = srcHeight / destHeight;
513. else {
514. int) Math.floor(srcHeight / destHeight) + 1;
515. }
516. // 循环建立切片
517. // 改进的想法:是否可用多线程加快切割速度
518. for (int i = 0; i < rows; i++) {
519. for (int j = 0; j < cols; j++) {
520. // 四个参数分别为图像起点坐标和宽高
521. // 即: CropImageFilter(int x,int y,int width,int height)
522. new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight);
523. img = Toolkit.getDefaultToolkit()
524. new FilteredImageSource(image.getSource(), cropFilter));
525. new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
526. Graphics g = tag.getGraphics();
527. 0, 0, null); // 绘制缩小后的图
528. g.dispose();
529. // 输出为文件
530. "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg"));
531. }
532. }
533. }
534. catch (Exception e) {
535. e.printStackTrace();
536. }
537. }
538.
539. /**
540. * 图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG
541. *
542. * @param srcImageFile
543. * 源图像地址
544. * @param formatName
545. * 包含格式非正式名称的 String:如JPG、JPEG、GIF等
546. * @param destImageFile
547. * 目标图像地址
548. */
549. public final static void convert(String srcImageFile, String formatName, String destImageFile) {
550. try {
551. new File(srcImageFile);
552. f.canRead();
553. f.canWrite();
554. BufferedImage src = ImageIO.read(f);
555. new File(destImageFile));
556. catch (Exception e) {
557. e.printStackTrace();
558. }
559. }
560.
561. /**
562. * 彩色转为黑白
563. *
564. * @param srcImageFile
565. * 源图像地址
566. * @param destImageFile
567. * 目标图像地址
568. */
569. public final static void gray(String srcImageFile, String destImageFile) {
570. try {
571. new File(srcImageFile));
572. ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
573. new ColorConvertOp(cs, null);
574. null);
575. "JPEG", new File(destImageFile));
576. catch (IOException e) {
577. e.printStackTrace();
578. }
579. }
580.
581. /**
582. * 给图片添加文字水印
583. *
584. * @param pressText
585. * 水印文字
586. * @param srcImageFile
587. * 源图像地址
588. * @param destImageFile
589. * 目标图像地址
590. * @param fontName
591. * 水印的字体名称
592. * @param fontStyle
593. * 水印的字体样式
594. * @param color
595. * 水印的字体颜色
596. * @param fontSize
597. * 水印的字体大小
598. * @param x
599. * 修正值
600. * @param y
601. * 修正值
602. * @param alpha
603. * 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
604. */
605. public final static void pressText(String pressText, String srcImageFile, String destImageFile, String fontName,
606. int fontStyle, Color color, int fontSize, int x, int y, float alpha) {
607. try {
608. new File(srcImageFile);
609. Image src = ImageIO.read(img);
610. int width = src.getWidth(null);
611. int height = src.getHeight(null);
612. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
613. Graphics2D g = image.createGraphics();
614. 0, 0, width, height, null);
615. g.setColor(color);
616. new Font(fontName, fontStyle, fontSize));
617. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
618. // 在指定坐标绘制水印文字
619. 2 + x, (height - fontSize) / 2 + y);
620. g.dispose();
621. "JPEG", new File(destImageFile));// 输出到文件流
622. catch (Exception e) {
623. e.printStackTrace();
624. }
625. }
626.
627. /**
628. * 给图片添加文字水印
629. *
630. * @param pressText
631. * 水印文字
632. * @param srcImageFile
633. * 源图像地址
634. * @param destImageFile
635. * 目标图像地址
636. * @param fontName
637. * 字体名称
638. * @param fontStyle
639. * 字体样式
640. * @param color
641. * 字体颜色
642. * @param fontSize
643. * 字体大小
644. * @param x
645. * 修正值
646. * @param y
647. * 修正值
648. * @param alpha
649. * 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
650. */
651. public final static void pressText2(String pressText, String srcImageFile, String destImageFile, String fontName,
652. int fontStyle, Color color, int fontSize, int x, int y, float alpha) {
653. try {
654. new File(srcImageFile);
655. Image src = ImageIO.read(img);
656. int width = src.getWidth(null);
657. int height = src.getHeight(null);
658. new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
659. Graphics2D g = image.createGraphics();
660. 0, 0, width, height, null);
661. g.setColor(color);
662. new Font(fontName, fontStyle, fontSize));
663. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
664. // 在指定坐标绘制水印文字
665. 2 + x, (height - fontSize) / 2 + y);
666. g.dispose();
667. "JPEG", new File(destImageFile));
668. catch (Exception e) {
669. e.printStackTrace();
670. }
671. }
672.
673. /**
674. * 给图片添加图片水印
675. *
676. * @param pressImg
677. * 水印图片
678. * @param srcImageFile
679. * 源图像地址
680. * @param destImageFile
681. * 目标图像地址
682. * @param x
683. * 修正值。 默认在中间
684. * @param y
685. * 修正值。 默认在中间
686. * @param alpha
687. * 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
688. */
689. public final static void pressImage(String pressImg, String srcImageFile, String destImageFile, int x, int y,
690. float alpha) {
691. try {
692. new File(srcImageFile);
693. Image src = ImageIO.read(img);
694. int wideth = src.getWidth(null);
695. int height = src.getHeight(null);
696. new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
697. Graphics2D g = image.createGraphics();
698. 0, 0, wideth, height, null);
699. // 水印文件
700. new File(pressImg));
701. int wideth_biao = src_biao.getWidth(null);
702. int height_biao = src_biao.getHeight(null);
703. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
704. 2, (height - height_biao) / 2, wideth_biao, height_biao,
705. null);
706. // 水印文件结束
707. g.dispose();
708. "JPEG", new File(destImageFile));
709. catch (Exception e) {
710. e.printStackTrace();
711. }
712. }
713.
714. /**
715. * 计算text的长度(一个中文算两个字符)
716. *
717. * @param text
718. * @return
719. */
720. public final static int getLength(String text) {
721. int length = 0;
722. for (int i = 0; i < text.length(); i++) {
723. if (new String(text.charAt(i) + "").getBytes().length > 1) {
724. 2;
725. else {
726. 1;
727. }
728. }
729. return length / 2;
730. }
731.
732. /**
733. * 缩放图像(按高度和宽度缩放)
734. *
735. * @param srcImageFile
736. * 源图像文件地址
737. * @param result
738. * 缩放后的图像地址
739. * @param height
740. * 缩放后的高度
741. * @param width
742. * 缩放后的宽度
743. */
744. public static void scale(String srcImageFile, String result, int maxWidth, int maxHeight) {
745. // 原图片
746. new File(srcImageFile);
747. // 目的图片
748. new File(result);
749. // 将图像缩略到指定尺寸以内,不足指定尺寸的则不做任何处理
750. new ScaleParameter(maxWidth, maxHeight);
751. null;
752. null;
753. null;
754. try {
755. new FileInputStream(in);
756. new FileOutputStream(out);
757. new ReadRender(inStream);
758. new ScaleRender(rr, scaleParam);
759. new WriteRender(sr, outStream);
760. // 执行图像处理
761. wr.render();
762. catch (Exception e) {
763. e.printStackTrace();
764. finally {
765. // 关闭图片文件输入输出流
766. IOUtils.closeQuietly(inStream);
767. IOUtils.closeQuietly(outStream);
768. if (wr != null) {
769. try {
770. // 释放simpleImage的内部资源
771. wr.dispose();
772. catch (SimpleImageException ignore) {
773. ignore.printStackTrace();
774. }
775. }
776. }
777. }
778.
779. /**
780. * 程序入口:用于测试
781. *
782. * @param args
783. */
784. public static void main(String[] args) {
785.
786. // 缩略图
787. // ImageUtils.scale("/Users/dewly/Downloads/TB1.9IXIFXXXXadaXXX2jHzFXXX_220x220.jpg",
788. // "/Users/dewly/Downloads/test00-118x118.jpg", 118, 118);
789. // ImageUtils.scale("d:/temp/1.png", "d:/temp/1_200x200.png", 200, 200);
790.
791. // 图片颜色处理(黑白彩色转换)
792. // ImageUtils.gray("e:/test/test.jpg", "e:/test/test2.jpg");// 测试OK
793.
794. // 方法一:按比例缩放(放大缩小)
795. "d:/temp/222.png", "d:/temp/222_111.png", 4, false);// 测试OK
796.
797. // 方法二:按高度和宽度缩放(放大缩小)
798. // ImageUtils.scale2("d:/temp/1.png", "d:/temp/1_720x720.png", 720,720,
799. // true);// 测试OK
800.
801. // 5-给图片添加文字水印:
802. // 方法一:
803. // ImageUtils.pressText("我是水印文字", "e:/test/g.jpg", "e:/test/g2.jpg",
804. // "宋体", Font.BOLD, Color.white, 80, 0, 0, 0.5f);// 测试OK
805. // 方法二:
806. // ImageUtils.pressText2("我也是水印文字", "e:/test/g.jpg", "e:/test/g3.jpg",
807. // "黑体", 36, Color.white, 80, 0, 0, 0.5f);// 测试OK
808. }
809. }
810.