java圖片合并 圖片寫(xiě)字多行換行

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();

}

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容