java給圖片新增文字水印,以及docker容器新增中文字型支援
阿新 • • 發佈:2018-12-20
發現雖然簡單,但是水印內容通過編碼拼接在圖片地址後面,每次訪問都要加上,如果要儲存下來還需要自己存第二遍有水印的圖。可是我們並不需要沒有水印的原圖,於是決定通過程式碼新增,更自由。
程式碼如下:
/** * 新增文字水印 * @param inputStream 原圖片 * @param waterMarkContent 水印文字內容陣列 * @param markContentColor 顏色 * @param font 字型 * @param format 圖片格式 * @return */ public static byte[] addWaterMark(byte[] inputStream, String[] waterMarkContent,Color markContentColor,Font font,String format) { ByteArrayOutputStream out = new ByteArrayOutputStream(); // printSysFont(); try { if(markContentColor==null) markContentColor=new Color(189, 66, 71, 255); //水印圖片色彩以及透明度 255是不透明 if(font==null) font = new Font("宋體", Font.PLAIN, 15); //水印字型 ByteArrayInputStream in = new ByteArrayInputStream(inputStream); //將b作為輸入流; Image srcImg = ImageIO.read(in); int srcImgWidth = srcImg.getWidth(null);//獲取圖片的寬 int srcImgHeight = srcImg.getHeight(null);//獲取圖片的高 // 加水印 BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufImg.createGraphics(); g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null); g.setColor(markContentColor); //根據圖片的背景設定水印顏色 g.setFont(font); //設定字型 //設定水印的座標 for(int i = 0;i<waterMarkContent.length;i++){ if(StringUtils.isBlank(waterMarkContent[i])) continue; System.out.println("內容:"+waterMarkContent[i]); int x = srcImgWidth - getWatermarkLength(waterMarkContent[i], g); int y = font.getSize()*(i+1); g.drawString(waterMarkContent[i], x>0?x:0, y); //畫出水印 System.out.println("畫出水印x:"+x+",y:"+y); } g.dispose(); // 輸出圖片 ImageIO.write(bufImg, format, out); System.out.println("新增水印完成"); byte[] ret = out.toByteArray(); return ret; } catch (Exception e) { e.printStackTrace(); return inputStream; // TODO: handle exception } } public static byte[] addWaterMark(byte[] inputStream, String[] waterMarkContent,String format) { return addWaterMark(inputStream, waterMarkContent, null, null,format); } /** * 要打上文字的長度 * @param waterMarkContent * @param g * @return */ private static int getWatermarkLength(String waterMarkContent, Graphics2D g) { return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length()); } private static GraphicsEnvironment environment;
其中因為水印內容預計有三行,分別是公司名,時間戳以及另一個內容,所以傳入的是字元陣列,它會一行一行印上去,傳入的是一個byte[],因為實在其它業務邏輯裡面新增的功能,所以返回也是byte 其它格式轉也很方便的。
使用:
String[] waterMarkContent = new String[3]; waterMarkContent[0] = "XXXXX"; waterMarkContent[1] = "XXXXX公司"; waterMarkContent[2] = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()); imageFile = ImageUtil.addWaterMark(imageFile, waterMarkContent, "jpg");
之後在我自己電腦上測試了一下沒什麼問題
專案通過docker部署,打包後發現中文顯示不出來!是框框!(圖片沒有留下來,懶得去重現了)
因為不是亂碼排除編碼格式問題,比較明顯是該環境下沒有對應的字型。
搜了一下解決辦法,比較好的解決方式是在dockerfile製作映象的時候把你要用的字型檔案放進去:
FROM java:8 ENV TZ=Asia/Shanghai RUN apt-get install tzdata RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 配置字型 COPY simsun.ttf /usr/share/fonts/simsun.ttf VOLUME /tmp ADD myApp.jar /app.jar EXPOSE 8085 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
OK,問題解決。希望能幫助遇到同樣問題的人,畢竟網上其他手動安裝,加入字型下載命令 等方式不太好用