package com.lcdt.driver.util;
import com.google.common.base.Strings;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import sun.font.FontDesignMetrics;
public class PictureMerge {
/**
? ? * @param fileUrl 文件絕對(duì)路徑或相對(duì)路徑
? ? * @return 讀取到的緩存圖像
? ? * @throws IOException 路徑錯(cuò)誤或者不存在該文件時(shí)拋出IO異常
? ? */
? ? public static BufferedImage getBufferedImage(String fileUrl)throws IOException {
BufferedImage bufferedImage =null;
// 構(gòu)造URL
? ? ? ? URL url =new URL(fileUrl);
// 打開(kāi)連接
? ? ? ? URLConnection con = url.openConnection();
// 輸入流
? ? ? ? InputStream is = con.getInputStream();
bufferedImage = ImageIO.read(is);
// 完畢,關(guān)閉所有鏈接
? ? ? ? is.close();
return bufferedImage;
}
/**
? ? * @param fileUrl 文件絕對(duì)路徑或相對(duì)路徑
? ? * @return 讀取到的緩存圖像
? ? * @throws IOException 路徑錯(cuò)誤或者不存在該文件時(shí)拋出IO異常
? ? */
? ? public static BufferedImage getBufferedImageLocal(String fileUrl)throws IOException {
return ImageIO.read(new File(fileUrl));
}
/**
? ? * 待合并的兩張圖必須滿足這樣的前提,如果水平方向合并,則高度必須相等;如果是垂直方向合并,寬度必須相等。 mergeImage方法不做判斷,自己判斷。
? ? *
? ? * @param img1 待合并的第一張圖
? ? * @param img2 帶合并的第二張圖
? ? * @return 返回合并后的BufferedImage對(duì)象
? ? * @throws IOException
*/
? ? public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2)
throws IOException {
int w1 = img1.getWidth();
int h1 = img1.getHeight();
int w2 = img2.getWidth();
int h2 = img2.getHeight();
// 從圖片中讀取RGB
? ? ? ? int[] ImageArrayOne =new int[w1 * h1];
ImageArrayOne = img1.getRGB(0,0, w1, h1, ImageArrayOne,0, w1);// 逐行掃描圖像中各個(gè)像素的RGB到數(shù)組中
? ? ? ? int[] ImageArrayTwo =new int[w2 * h2];
ImageArrayTwo = img2.getRGB(0,0, w2, h2, ImageArrayTwo,0, w2);
// 生成新圖片
? ? ? ? BufferedImage DestImage =null;
DestImage =new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0,0, w1, h1, ImageArrayOne,0, w1);// 設(shè)置上半部分或左半部分的RGB
? ? ? ? DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo,0, w2);// 設(shè)置下半部分的RGB
? ? ? ? return DestImage;
}
/**
? ? * <p>Title: getImageStream</p>? ? * <p>Description: 獲取圖片InputStream</p>*
? ? * @param destImg
? ? * @return
? ? */
? ? public static InputStream getImageStream(BufferedImage destImg) {
InputStream is =null;
BufferedImage bi = destImg;
ByteArrayOutputStream bs =new ByteArrayOutputStream();
ImageOutputStream imOut;
try {
imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(bi,"png", imOut);
is =new ByteArrayInputStream(bs.toByteArray());
}catch (IOException e) {
e.printStackTrace();
}
return is;
}
/**
? ? * <p>Title: drawTextInImg</p>? ? * <p>Description: 圖片上添加文字業(yè)務(wù)需求要在圖片上添加水</p>*
? ? * @param text
? ? */
? ? public static BufferedImage drawTextInImg( String text) {
int srcImgWidth =430;
int fontSize =14;
Font font =new Font("Microsoft YaHei", Font.PLAIN, fontSize);
int fontlen =getWatermarkLength(text, font);
int line = fontlen / srcImgWidth;//文字長(zhǎng)度相對(duì)于圖片寬度應(yīng)該有多少行
? ? ? ? int srcImgHeight = (line +2) * fontSize;;
BufferedImage bimage =new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bimage.createGraphics();
g.setColor(Color.white);
g.fillRect(0,0, srcImgWidth, srcImgHeight);
drawText(g, text, srcImgWidth, font,0,0,0,null,null);
g.dispose();
return bimage;
}
/**
? ? * <p>Title: drawTextInImg</p>? ? * <p>Description: 圖片上添加文字業(yè)務(wù)需求要在圖片上添加水</p>*
? ? * @param
? ? */
? ? public static BufferedImage drawTextInImg( Map map) {
int srcImgWidth =1500;
int fontSize =88;
int rowSpacing =50;
Map attributes =new HashMap<>();
attributes.put(TextAttribute.FAMILY,"Microsoft YaHei");
attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_MEDIUM);
attributes.put(TextAttribute.SIZE, fontSize);
Font font = Font.getFont(attributes);
attributes.put(TextAttribute.FAMILY,"Microsoft YaHei");
attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_MEDIUM);
attributes.put(TextAttribute.SIZE,66);
Font keyFont = Font.getFont(attributes);
/*int line = 0;
for (String key: map.keySet() ) {
String text = key + Strings.nullToEmpty(map.get(key));
int fontlen = getWatermarkLength(text, font);
if(fontlen < srcImgWidth){
line += 1;
}else{
? ? ? ? ? ? ? ? line += fontlen / srcImgWidth;//文字長(zhǎng)度相對(duì)于圖片寬度應(yīng)該有多少行}
}
int srcImgHeight = (line + 2) * (fontSize+rowSpacing);*/
? ? ? ? int srcImgHeight =1100;
BufferedImage bimage =new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bimage.createGraphics();
g.setColor(Color.white);
g.fillRect(0,0, srcImgWidth, srcImgHeight);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
int beginY =0;
int beginX =90 +40;
int valueBeginX = beginX + fontSize*5;
int keyMaxWidth =100*4;
int valueMaxWidth = srcImgWidth - keyMaxWidth -200;
for (String key: map.keySet() ) {
beginY += (fontSize+rowSpacing);
drawText(g, key, keyMaxWidth, keyFont,beginX,beginY +20,rowSpacing,new Color(255,117,0),Color.white);
drawText(g, map.get(key), valueMaxWidth, font,valueBeginX,beginY,rowSpacing,null,null);
}
g.dispose();
return bimage;
}
/**
? ? * <p>Title: drawTextInImg</p>? ? * <p>Description: 圖片上添加文字業(yè)務(wù)需求要在圖片上添加水</p>*
*/
? ? public static BufferedImage drawImgInImg( BufferedImage targetImg, BufferedImage img,int beginX,int beginY,int zoom) {
Graphics2D g = targetImg.createGraphics();
g.drawImage(img, beginX,beginY,img.getWidth()/zoom,img.getHeight()/zoom,null);
g.dispose();
return targetImg;
}
static void drawText(Graphics2D g, String text,int srcImgWidth, Font font,int beginX,
int beginY,int rowSpacing, Color backGroundColor,Color fontColor){
if(backGroundColor !=null){
g.setColor(backGroundColor);
g.fillRect(beginX-40,beginY-5,font.getSize()*4+50*2,font.getSize()+15*2);
}
if(fontColor !=null){
g.setColor(fontColor);
}else{
g.setColor(Color.black);
}
g.setFont(font);
int fontSize = font.getSize();
//文字疊加,自動(dòng)換行疊加
? ? ? ? int tempX = beginX+2;
int tempY = beginY + fontSize;
int tempCharLen =0;//單字符長(zhǎng)度
? ? ? ? int tempLineLen =0;//單行字符總長(zhǎng)度臨時(shí)計(jì)算
? ? ? ? StringBuffer sb =new StringBuffer();
int textMaxWidth = srcImgWidth -10;
for (int i =0; i < text.length(); i++) {
char tempChar = text.charAt(i);
tempCharLen =getCharLen(tempChar, g);
tempLineLen += tempCharLen;
if (tempLineLen >= textMaxWidth) {
//長(zhǎng)度已經(jīng)滿一行,進(jìn)行文字疊加
? ? ? ? ? ? ? ? g.drawString(sb.toString(), tempX, tempY);
sb.delete(0, sb.length());//清空內(nèi)容,重新追加
? ? ? ? ? ? ? ? tempY += (fontSize + rowSpacing);
tempLineLen =0;
}
sb.append(tempChar);//追加字符
? ? ? ? }
g.drawString(sb.toString(), tempX, tempY);//最后疊加余下的文字
? ? }
/**
? ? * 獲取水印文字總長(zhǎng)度
? ? *
? ? * @paramwaterMarkContent水印的文字
? ? * @paramg
? ? * @return水印文字總長(zhǎng)度
? ? */
? ? public static int getWatermarkLength(String waterMarkContent, Font font) {
return FontDesignMetrics.getMetrics(font)
.charsWidth(waterMarkContent.toCharArray(),0, waterMarkContent.length());
}
public static int getCharLen(char c, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charWidth(c);
}
public static BufferedImage test(){
BufferedImage bufferedImage =null;
try {
String text ="java項(xiàng)目開(kāi)發(fā)難免會(huì)遇到不同的客戶的需求,沒(méi)錯(cuò)我們要不斷的滿足客戶的需求。今天在項(xiàng)目遇到一個(gè)將兩張圖片縱向拼接起來(lái)成為一張圖片";
text ="文學(xué)是一種語(yǔ)言藝術(shù),是話語(yǔ)蘊(yùn)藉中的審美意識(shí)形態(tài)。詩(shī)歌、散文、小說(shuō)、劇本、寓言、童話等不同體裁,是文學(xué)的重要表現(xiàn)形式。文學(xué)以不同的形式即體裁,表現(xiàn)內(nèi)心情感,再現(xiàn)一定時(shí)期和一定地域的社會(huì)生活。作為學(xué)科門(mén)類理解的文學(xué),包括中國(guó)語(yǔ)言文學(xué)、外國(guó)語(yǔ)言文學(xué)及新聞傳播學(xué)。\n"
? ? ? ? ? ? ? ? +"文學(xué)是屬于人文學(xué)科的學(xué)科分類之一,與哲學(xué)、宗教、法律、政治并駕于社會(huì)建筑上層。它起源于人類的思維活動(dòng)。最先出現(xiàn)的是口頭文學(xué),一般是與音樂(lè)聯(lián)結(jié)為可以演唱的抒情詩(shī)歌。最早形成書(shū)面文學(xué)的有中國(guó)的《詩(shī)經(jīng)》、印度的《羅摩衍那》和古希臘的《伊利昂紀(jì)》等。中國(guó)先秦時(shí)期將以文字寫(xiě)成的作品都統(tǒng)稱為文學(xué),魏晉以后才逐漸將文學(xué)作品單獨(dú)列出。歐洲傳統(tǒng)文學(xué)理論分類法將文學(xué)分為詩(shī)、散文、戲劇三大類?,F(xiàn)代通常將文學(xué)分為詩(shī)歌、小說(shuō)、散文、戲劇四大類別。\n"
? ? ? ? ? ? ? ? +"文學(xué)是語(yǔ)言文字的藝術(shù),是社會(huì)文化的一種重要表現(xiàn)形式,是對(duì)美的體現(xiàn)。文學(xué)作品是作家用獨(dú)特的語(yǔ)言藝術(shù)表現(xiàn)其獨(dú)特的心靈世界的作品,離開(kāi)了這樣兩個(gè)極具個(gè)性特點(diǎn)的獨(dú)特性就沒(méi)有真正的文學(xué)作品。一個(gè)杰出的文學(xué)家就是一個(gè)民族心靈世界的英雄。文學(xué)代表一個(gè)民族的藝術(shù)和智慧。文學(xué),是一種將語(yǔ)言文字用于表達(dá)社會(huì)生活和心理活動(dòng)的學(xué)科,屬社會(huì)意識(shí)形態(tài)范疇。";
bufferedImage =getBufferedImage("D:\\temp\\loading.jpg");
BufferedImage bufferedImage1 =drawTextInImg(text);
bufferedImage =mergeImage(bufferedImage1,bufferedImage);
}catch (IOException e) {
e.printStackTrace();
}
return bufferedImage;
}
public static void main(String[] args) {
BufferedImage bufferedImage =null;
try {
/*String text = "java項(xiàng)目開(kāi)發(fā)難免會(huì)遇到不同的客戶的需求,沒(méi)錯(cuò)我們要不斷的滿足客戶的需求。今天在項(xiàng)目遇到一個(gè)將兩張圖片縱向拼接起來(lái)成為一張圖片";
? ? ? ? ? ? text = "文學(xué)是一種語(yǔ)言藝術(shù),是話語(yǔ)蘊(yùn)藉中的審美意識(shí)形態(tài)。詩(shī)歌、散文、小說(shuō)、劇本、寓言、童話等不同體裁,是文學(xué)的重要表現(xiàn)形式。文學(xué)以不同的形式即體裁,表現(xiàn)內(nèi)心情感,再現(xiàn)一定時(shí)期和一定地域的社會(huì)生活。作為學(xué)科門(mén)類理解的文學(xué),包括中國(guó)語(yǔ)言文學(xué)、外國(guó)語(yǔ)言文學(xué)及新聞傳播學(xué)。\n"
? ? ? ? ? ? ? ? + "文學(xué)是屬于人文學(xué)科的學(xué)科分類之一,與哲學(xué)、宗教、法律、政治并駕于社會(huì)建筑上層。它起源于人類的思維活動(dòng)。最先出現(xiàn)的是口頭文學(xué),一般是與音樂(lè)聯(lián)結(jié)為可以演唱的抒情詩(shī)歌。最早形成書(shū)面文學(xué)的有中國(guó)的《詩(shī)經(jīng)》、印度的《羅摩衍那》和古希臘的《伊利昂紀(jì)》等。中國(guó)先秦時(shí)期將以文字寫(xiě)成的作品都統(tǒng)稱為文學(xué),魏晉以后才逐漸將文學(xué)作品單獨(dú)列出。歐洲傳統(tǒng)文學(xué)理論分類法將文學(xué)分為詩(shī)、散文、戲劇三大類?,F(xiàn)代通常將文學(xué)分為詩(shī)歌、小說(shuō)、散文、戲劇四大類別。\n"
? ? ? ? ? ? ? ? + "文學(xué)是語(yǔ)言文字的藝術(shù),是社會(huì)文化的一種重要表現(xiàn)形式,是對(duì)美的體現(xiàn)。文學(xué)作品是作家用獨(dú)特的語(yǔ)言藝術(shù)表現(xiàn)其獨(dú)特的心靈世界的作品,離開(kāi)了這樣兩個(gè)極具個(gè)性特點(diǎn)的獨(dú)特性就沒(méi)有真正的文學(xué)作品。一個(gè)杰出的文學(xué)家就是一個(gè)民族心靈世界的英雄。文學(xué)代表一個(gè)民族的藝術(shù)和智慧。文學(xué),是一種將語(yǔ)言文字用于表達(dá)社會(huì)生活和心理活動(dòng)的學(xué)科,屬社會(huì)意識(shí)形態(tài)范疇。";
bufferedImage = getBufferedImage("D:\\temp\\loading.jpg");
BufferedImage bufferedImage1 = drawTextInImg(text);
ImageIO.write(bufferedImage1, "jpg", new File("D:\\temp\\loading1.jpg"));
ImageIO.write(mergeImage(bufferedImage1,bufferedImage), "jpg", new File("D:\\temp\\loading1.jpg"));*/
? ? ? ? ? ? Map map =new LinkedHashMap<>();
map.put("始發(fā)地","濟(jì)南");
map.put("目的地","青島");
map.put("車(chē)輛要求","1.5板車(chē)");
map.put("聯(lián)系方式","18896543217");
map.put("其他要求","明天截止,明天截止,明天截止,明天截止,明天截止,明天截止,明天截止");
String templateFile ="https://clms-dtd.oss-cn-beijing.aliyuncs.com/static/share-template.png";
bufferedImage =getBufferedImage(templateFile);
BufferedImage img =getBufferedImageLocal("E:\\temp\\footer-left.png");
int beginY = bufferedImage.getHeight() - img.getHeight() -10;
int beginX =50;
bufferedImage =drawImgInImg(bufferedImage,img,beginX,beginY,1);
BufferedImage txtImg =drawTextInImg(map);
beginY =520;
beginX =0;
bufferedImage =drawImgInImg(bufferedImage,txtImg,beginX,beginY,1);
ImageIO.write(bufferedImage,"png",
new File("E:\\temp\\loading1.png"));
}catch (IOException e) {
e.printStackTrace();
}
}
}