ImagesUtil.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package com.izouma.awesomeadmin.util;
  2. import org.apache.commons.io.FileUtils;
  3. import sun.misc.BASE64Decoder;
  4. import javax.imageio.IIOException;
  5. import javax.imageio.ImageIO;
  6. import javax.imageio.ImageReader;
  7. import javax.imageio.stream.ImageInputStream;
  8. import javax.imageio.stream.ImageOutputStream;
  9. import java.awt.*;
  10. import java.awt.color.ColorSpace;
  11. import java.awt.image.*;
  12. import java.io.*;
  13. import java.util.Iterator;
  14. public class ImagesUtil {
  15. //base64字符串转化成图片
  16. /**
  17. * <p>base64字符串转化成图片流。</p>
  18. *
  19. * @param imgStr
  20. * @return
  21. */
  22. public static InputStream GenerateImage(String imgStr) { //对字节数组字符串进行Base64解码并生成图片
  23. if (imgStr == null) //图像数据为空
  24. return null;
  25. imgStr = imgStr.substring(imgStr.indexOf(',') + 1);
  26. try {
  27. //Base64解码
  28. // byte[] b = Base64.getDecoder().decode(imgStr);
  29. byte[] b = new BASE64Decoder().decodeBuffer(imgStr);
  30. for (int i = 0; i < b.length; ++i) {
  31. if (b[i] < 0) {//调整异常数据
  32. b[i] += 256;
  33. }
  34. }
  35. InputStream sbs = new ByteArrayInputStream(b);
  36. //生成jpeg图片
  37. // out.write();
  38. // out.flush();
  39. // out.close();
  40. // //生成jpeg图片
  41. // InputStream in = null;
  42. return sbs;
  43. } catch (Exception e) {
  44. return null;
  45. }
  46. }
  47. /**
  48. * 等比例压缩算法:
  49. * 算法思想:根据压缩基数和压缩比来压缩原图,生产一张图片效果最接近原图的缩略图
  50. *
  51. * @param fin 原图
  52. * @param imageType 图片类型
  53. * @param comBase 压缩基数
  54. * @param scale 压缩限制(宽/高)比例 一般用1:
  55. * 当scale>=1,缩略图height=comBase,width按原图宽高比例;若scale<1,缩略图width=comBase,height按原图宽高比例
  56. * @throws Exception
  57. */
  58. public static InputStream changeMinPhotoOld(InputStream fin, String imageType, double comBase,
  59. double scale) {
  60. try {
  61. // get image format in a file
  62. //File file = new File("newimage.jpg");
  63. // create an image input stream from the specified file
  64. ImageInputStream iis = ImageIO.createImageInputStream(fin);
  65. Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
  66. if (readers == null || !readers.hasNext()) {
  67. throw new RuntimeException("1 No ImageReaders found");
  68. }
  69. ImageReader reader = (ImageReader) readers.next();
  70. reader.setInput(iis);
  71. String format = reader.getFormatName();
  72. BufferedImage image = null;
  73. if ("JPEG".equalsIgnoreCase(format) || "JPG".equalsIgnoreCase(format) || "PNG".equalsIgnoreCase(format) || "CR2".equalsIgnoreCase(format)) {
  74. try {
  75. // 尝试读取图片 (包括颜色的转换).
  76. image = reader.read(0); //RGB
  77. } catch (IIOException e) {
  78. // 读取Raster (没有颜色的转换).
  79. Raster raster = reader.readRaster(0, null);//CMYK
  80. image = createJPEG4(raster);
  81. }
  82. }
  83. int srcHeight = image.getHeight();
  84. int srcWidth = image.getWidth(null);
  85. int deskHeight = 0;// 缩略图高
  86. int deskWidth = 0;// 缩略图宽
  87. double srcScale = (double) srcHeight / srcWidth;
  88. /**缩略图宽高算法*/
  89. if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
  90. if (srcScale >= scale || 1 / srcScale > scale) {
  91. if (srcScale >= scale) {
  92. deskHeight = (int) comBase;
  93. deskWidth = srcWidth * deskHeight / srcHeight;
  94. } else {
  95. deskWidth = (int) comBase;
  96. deskHeight = srcHeight * deskWidth / srcWidth;
  97. }
  98. } else {
  99. if ((double) srcHeight > comBase) {
  100. deskHeight = (int) comBase;
  101. deskWidth = srcWidth * deskHeight / srcHeight;
  102. } else {
  103. deskWidth = (int) comBase;
  104. deskHeight = srcHeight * deskWidth / srcWidth;
  105. }
  106. }
  107. } else {
  108. deskHeight = srcHeight;
  109. deskWidth = srcWidth;
  110. }
  111. BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR);
  112. tag.getGraphics().drawImage(image, 0, 0, deskWidth, deskHeight, null); //绘制缩小后的图
  113. //BufferedImage 转 InputStream
  114. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  115. ImageOutputStream imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream);
  116. ImageIO.write(tag, imageType, imageOutput);
  117. InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
  118. return inputStream;
  119. } catch (Exception e) {
  120. e.printStackTrace();
  121. }
  122. return null;
  123. }
  124. /**
  125. * 图片压缩
  126. *
  127. * @param fin
  128. * @param imageType
  129. * @return
  130. */
  131. public static InputStream changeMinPhoto(InputStream fin, String imageType) {
  132. try {
  133. ByteArrayOutputStream baos = cloneInputStream(fin);
  134. String tmpImagename = "CMYK_" + MbappUtil.create_nonce_str() + "." + imageType;
  135. File src = new File("/var/www/tmp/" + tmpImagename);
  136. FileUtils.copyInputStreamToFile(new ByteArrayInputStream(baos.toByteArray()), src);
  137. String[] cmd = {"sh", "-c", "convert -resize '4000000@>' -quality 60 /var/www/tmp/" + tmpImagename + " /var/www/tmp/RGB" + tmpImagename};
  138. //System.out.println("1xxxx:" + new Date());
  139. Process p = Runtime.getRuntime().exec(cmd);
  140. //System.out.println("2xxxx:" + new Date());
  141. printMessage(p.getInputStream());
  142. printMessage(p.getErrorStream());
  143. p.waitFor();
  144. //System.out.println("3xxxx:" + new Date());
  145. InputStream inputStream = new FileInputStream(new File("/var/www/tmp/RGB" + tmpImagename));
  146. //System.out.println("4xxxx:" + new Date());
  147. if (!"".equals(tmpImagename)) {//清楚临时文件
  148. deleteFile("/var/www/tmp/" + tmpImagename);
  149. deleteFile("/var/www/tmp/RGB" + tmpImagename);
  150. }
  151. return inputStream;
  152. } catch (Exception ee) {
  153. ee.printStackTrace();
  154. }
  155. return null;
  156. }
  157. private static void printMessage(final InputStream input) {
  158. new Thread(new Runnable() {
  159. public void run() {
  160. Reader reader = new InputStreamReader(input);
  161. BufferedReader bf = new BufferedReader(reader);
  162. String line = null;
  163. try {
  164. while ((line = bf.readLine()) != null) {
  165. System.out.println(line);
  166. }
  167. } catch (IOException e) {
  168. e.printStackTrace();
  169. }
  170. }
  171. }).start();
  172. }
  173. private static ByteArrayOutputStream cloneInputStream(InputStream input) {
  174. try {
  175. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  176. byte[] buffer = new byte[1024];
  177. int len;
  178. while ((len = input.read(buffer)) > -1) {
  179. baos.write(buffer, 0, len);
  180. }
  181. baos.flush();
  182. return baos;
  183. } catch (IOException e) {
  184. e.printStackTrace();
  185. return null;
  186. }
  187. }
  188. private static BufferedImage createJPEG4(Raster raster) {
  189. int w = raster.getWidth();
  190. int h = raster.getHeight();
  191. byte[] rgb = new byte[w * h * 3];
  192. //彩色空间转换
  193. float[] Y = raster.getSamples(0, 0, w, h, 0, (float[]) null);
  194. float[] Cb = raster.getSamples(0, 0, w, h, 1, (float[]) null);
  195. float[] Cr = raster.getSamples(0, 0, w, h, 2, (float[]) null);
  196. float[] K = raster.getSamples(0, 0, w, h, 3, (float[]) null);
  197. for (int i = 0, imax = Y.length, base = 0; i < imax; i++, base += 3) {
  198. float k = 220 - K[i], y = 255 - Y[i], cb = 255 - Cb[i],
  199. cr = 255 - Cr[i];
  200. double val = y + 1.402 * (cr - 128) - k;
  201. val = (val - 128) * .65f + 128;
  202. rgb[base] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
  203. : (byte) (val + 0.5);
  204. val = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128) - k;
  205. val = (val - 128) * .65f + 128;
  206. rgb[base + 1] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
  207. : (byte) (val + 0.5);
  208. val = y + 1.772 * (cb - 128) - k;
  209. val = (val - 128) * .65f + 128;
  210. rgb[base + 2] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
  211. : (byte) (val + 0.5);
  212. }
  213. raster = Raster.createInterleavedRaster(new DataBufferByte(rgb, rgb.length), w, h, w * 3, 3, new int[]{0, 1, 2}, null);
  214. ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
  215. ColorModel cm = new ComponentColorModel(cs, false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
  216. return new BufferedImage(cm, (WritableRaster) raster, true, null);
  217. }
  218. /**
  219. * 删除单个文件
  220. *
  221. * @param fileName 要删除的文件的文件名
  222. * @return 单个文件删除成功返回true,否则返回false
  223. */
  224. public static boolean deleteFile(String fileName) {
  225. File file = new File(fileName);
  226. // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
  227. if (file.exists() && file.isFile()) {
  228. if (file.delete()) {
  229. System.out.println("删除单个文件" + fileName + "成功!");
  230. return true;
  231. } else {
  232. System.out.println("删除单个文件" + fileName + "失败!");
  233. return false;
  234. }
  235. } else {
  236. System.out.println("删除单个文件失败:" + fileName + "不存在!");
  237. return false;
  238. }
  239. }
  240. }