圖片壓縮並新增水印文字
阿新 • • 發佈:2021-09-08
注意:
- JPEGCodec在JDK1.7下編譯會報錯,該類已從jdk移除,可使用ImageIO.write替代。
- Graphics2D 類 drawString 方法新增水印時,如果水印包含中文,且專案部署在Linux系統,需將中文字型上傳至Linux伺服器的/usr/share/fonts/目錄下,若使用容器則將字型檔案複製到容器中的/usr/share/fonts/目錄下。否則中文水印內容變成方框亂碼。
程式碼示例:
1 package com.macronet.pub.util; 2 3 import java.awt.Color; 4 import java.awt.Font;5 import java.awt.Graphics2D; 6 import java.awt.Image; 7 import java.awt.image.BufferedImage; 8 import java.io.File; 9 import java.io.FileOutputStream; 10 import java.io.IOException; 11 import javax.imageio.ImageIO; 12 13 public class CompressPic { 14 15 /*******************************************************************************16 * 縮圖類(通用) 本java類能將jpg、bmp、png、gif圖片檔案,進行等比或非等比的大小轉換。 具體使用方法 17 * compressPic(大圖片路徑,生成小圖片路徑,大圖片檔名,生成小圖片文名,生成小圖片寬度,生成小圖片高度,是否等比縮放(預設為true)) 18 */ 19 private File file = null; // 檔案物件 20 private String inputDir; // 輸入圖路徑 21 private String outputDir; // 輸出圖路徑 22 private String inputFileName; //輸入圖檔名 23 private String outputFileName; // 輸出圖檔名 24 private int outputWidth = 100; // 預設輸出圖片寬 25 private int outputHeight = 100; // 預設輸出圖片高 26 private boolean proportion = true; // 是否等比縮放標記(預設為等比縮放) 27 28 public CompressPic() { // 初始化變數 29 inputDir = ""; 30 outputDir = ""; 31 inputFileName = ""; 32 outputFileName = ""; 33 outputWidth = 100; 34 outputHeight = 100; 35 } 36 37 public void setInputDir(String inputDir) { 38 this.inputDir = inputDir; 39 } 40 41 public void setOutputDir(String outputDir) { 42 this.outputDir = outputDir; 43 } 44 45 public void setInputFileName(String inputFileName) { 46 this.inputFileName = inputFileName; 47 } 48 49 public void setOutputFileName(String outputFileName) { 50 this.outputFileName = outputFileName; 51 } 52 53 public void setOutputWidth(int outputWidth) { 54 this.outputWidth = outputWidth; 55 } 56 57 public void setOutputHeight(int outputHeight) { 58 this.outputHeight = outputHeight; 59 } 60 61 public void setWidthAndHeight(int width, int height) { 62 this.outputWidth = width; 63 this.outputHeight = height; 64 } 65 66 /* 67 * 獲得圖片大小 傳入引數 String path :圖片路徑 68 */ 69 public long getPicSize(String path) { 70 file = new File(path); 71 return file.length(); 72 } 73 74 // 圖片處理 75 public String compressPic() { 76 try { 77 // 獲得原始檔 78 file = new File(inputDir + inputFileName); 79 //System.out.println(inputDir + inputFileName); 80 if (!file.exists()) { 81 System.out.println(" can't read file " + inputDir + inputFileName); 82 return "no"; 83 } 84 Image img = ImageIO.read(file); 85 // 判斷圖片格式是否正確 86 if (img.getWidth(null) == -1) { 87 System.out.println(" can't read,retry!" + "<BR>"); 88 return "no"; 89 } else { 90 int newWidth; 91 int newHeight; 92 // 判斷是否是等比縮放 93 if (this.proportion == true) { 94 // 為等比縮放計算輸出的圖片寬度及高度 95 double rate1 = ((double) img.getWidth(null)) 96 / (double) outputWidth + 0.1; 97 double rate2 = ((double) img.getHeight(null)) 98 / (double) outputHeight + 0.1; 99 // 根據縮放比率大的進行縮放控制 100 double rate = rate1 > rate2 ? rate1 : rate2; 101 newWidth = (int) (((double) img.getWidth(null)) / rate); 102 newHeight = (int) (((double) img.getHeight(null)) / rate); 103 } else { 104 newWidth = outputWidth; // 輸出的圖片寬度 105 newHeight = outputHeight; // 輸出的圖片高度 106 } 107 BufferedImage tag = new BufferedImage((int) newWidth, 108 (int) newHeight, BufferedImage.TYPE_INT_RGB); 109 110 /* 111 * Image.SCALE_SMOOTH 的縮略演算法 生成縮圖片的平滑度的 優先順序比速度高 生成的圖片質量比較好 但速度慢 112 */ 113 tag.getGraphics().drawImage( 114 img.getScaledInstance(newWidth, newHeight, 115 Image.SCALE_SMOOTH), 0, 0, null); 116 // 加水印 117 Graphics2D g = tag.createGraphics(); 118 //g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null); 119 Color color = Color.red; 120 g.setColor(color); //根據圖片的背景設定水印顏色 121 Font font = new Font("宋體", Font.ITALIC, 24); 122 g.setFont(font); //設定字型 123 String waterMarkContent="圖片僅限個人物品郵件報關使用"; //水印內容 124 // 一行14個位置,超出部分進行換行 125 int page = (int) Math.ceil((double)waterMarkContent.length()/8); 126 for (int i = 0; i < page; i++) { 127 String sub = null; 128 if ((i+1)*8 < waterMarkContent.length()) { 129 sub = waterMarkContent.substring(i*8, (i+1)*8); 130 } else { 131 sub = waterMarkContent.substring(i*8, waterMarkContent.length()); 132 } 133 g.drawString(sub, newWidth/2-100, newHeight/2-100+i*30); // 畫文字 134 } 135 g.dispose(); 136 137 if(outputDir!=null && !"".equals(outputDir)) { 138 File f=new File(outputDir); 139 if (!f.exists()){ 140 f.mkdirs(); 141 } 142 } 143 FileOutputStream out = new FileOutputStream(outputDir 144 + outputFileName); 145 // JPEGImageEncoder可適用於其他圖片型別的轉換 146 // JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 147 // encoder.encode(tag); 148 ImageIO.write(tag, "jpg", out); 149 out.close(); 150 } 151 } catch (IOException ex) { 152 ex.printStackTrace(); 153 return "no"; 154 } 155 return "ok"; 156 } 157 158 public String compressPic(String outputDir, String inputFileName, 159 String outputFileName) { 160 // 輸出圖路徑 161 this.outputDir = outputDir; 162 // 輸入圖檔名 163 this.inputFileName = inputFileName; 164 // 輸出圖檔名 165 this.outputFileName = outputFileName; 166 return compressPic(); 167 } 168 169 public String compressPic(String outputDir, String inputFileName, 170 String outputFileName, int size) { 171 if(outputDir.lastIndexOf("/")!=(outputDir.length()-1)) { 172 outputDir+="/"; 173 } 174 175 // 輸出圖路徑 176 this.inputDir = outputDir; 177 this.outputDir = outputDir; 178 // 輸入圖檔名 179 this.inputFileName = inputFileName; 180 // 輸出圖檔名 181 this.outputFileName = outputFileName; 182 183 this.outputHeight=size; 184 this.outputWidth=size; 185 186 return compressPic(); 187 } 188 189 public String compressPic(String inputDir, String outputDir, 190 String inputFileName, String outputFileName, int width, int height, 191 boolean gp) { 192 // 輸入圖路徑 193 this.inputDir = inputDir; 194 // 輸出圖路徑 195 this.outputDir = outputDir; 196 // 輸入圖檔名 197 this.inputFileName = inputFileName; 198 // 輸出圖檔名 199 this.outputFileName = outputFileName; 200 // 設定圖片長寬 201 setWidthAndHeight(width, height); 202 // 是否是等比縮放 標記 203 this.proportion = gp; 204 return compressPic(); 205 } 206 207 }