java 使用Graphics2D在圖片上寫字
使用Graphics2D在圖片上寫字
首先jsp頁面:src是一個方法地址

然后在Controller如下:寫一個生成方法,用流進行讀寫

生成方法,(關(guān)鍵):


注意:這種方法可行,但是需要計算文字的位置,感覺不太靈活,如果誰有更好的方法請分享一下。
Graphics2D 的使用
1、Graphics2D和Graphics的區(qū)別
此 Graphics2D 類擴展Graphics 類,以提供對幾何形狀、坐標轉(zhuǎn)換、顏色管理和文本布局更為復雜的控制。它是用于在Java(tm) 平臺上呈現(xiàn)二維形狀、文本和圖像的基礎(chǔ)類。
tips:總而言之Graphics2D是Graphics的加強版,增強了一些高級操作。
2、setRenderingHint的具體用處
為呈現(xiàn)算法設(shè)置單個首選項的值。提示類別包括對呈現(xiàn)過程中的呈現(xiàn)質(zhì)量和總時間/質(zhì)量折衷的控制。
tips:對呈現(xiàn)圖像效果處理方式進行設(shè)置,例如抗鋸齒、顏色、差值等各種效果的處理算法。(我現(xiàn)在主要覺得抗鋸齒有用,以后會有不同的感受吧。)下面是兩個對比圖。
未開啟抗鋸齒

開啟抗鋸齒

下面是代碼實現(xiàn):
BufferedImage image = new BufferedImage(260, 80, BufferedImage.TYPE_INT_BGR);
//獲取Graphics2D對象
Graphics2D graphics = image.createGraphics();
//開啟文字抗鋸齒
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//設(shè)置字體
Font font = new Font("Algerian", Font.ITALIC, 40);
graphics.setFont(font);
//向畫板上寫字
graphics.drawString("This is test!", 10, 60);
graphics.dispose();
3、Stroke的使用方法
描繪一個 Shape 如同使用一支具有適當大小和形狀的畫筆描繪其輪廓。
tips:相當于畫筆頭,用來定義畫出來的線條的特征;通過設(shè)置不同的參數(shù)來表現(xiàn)出各種不同的線條類型。更多詳細介紹可以觀看BasicStroke的用法這篇文章,里面有詳細敘述。
下面是我自己寫的一個小例子(指定背景圖,并畫一個樹):
package com.msw.test;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
public class MyTest {
public static void main(String[] args) throws IOException {
BufferedImage image = new BufferedImage(400, 500, BufferedImage.TYPE_INT_BGR);
BufferedImage image2 = ImageIO.read(new FileInputStream(new File("F:\\2.jpg")));
// 獲取Graphics2D對象
Graphics2D graphics = image.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
//把image2設(shè)置為背景圖片
graphics.drawImage(image2, 0, 0, 400, 500,null);
// 設(shè)置畫筆
Stroke stroke = new BasicStroke(5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
graphics.setStroke(stroke);
// 設(shè)置顏色--綠色
graphics.setColor(Color.GREEN);
//畫樹
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Polygon polygon = new Polygon();
polygon.addPoint(200, 100);
polygon.addPoint(180, 150);
polygon.addPoint(220, 150);
graphics.draw(polygon);
polygon.reset();
polygon.addPoint(200, 150);
polygon.addPoint(160, 200);
polygon.addPoint(240, 200);
graphics.draw(polygon);
polygon.reset();
polygon.addPoint(200, 200);
polygon.addPoint(140, 250);
polygon.addPoint(260, 250);
graphics.draw(polygon);
polygon.reset();
polygon.addPoint(180, 250);
polygon.addPoint(180, 300);
polygon.addPoint(220, 300);
polygon.addPoint(220, 250);
graphics.draw(polygon);
graphics.dispose();
File file = new File("F:\\1.jpg");
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ImageIO.write(image, "jpg", fos);
fos.close();
}
}
使用Graphics2D圖片上寫字,計算寬和高 以及字體的位置

如上圖,這個是一個有中文與英文的字符串。 中文與英文字符的寬高是不一樣的,如果想要生成一張寬高剛的圖片,這樣我就需要計算每一個字符的寬度,及合適的高;
java.awt.FontMetrics 這個類對文字的寬高位置有詳細的介紹;
計算使用字體的一段字符串的寬
public static int getWordWidth(Font font, String content) {
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int width = 0;
for (int i = 0; i < content.length(); i++) {
width += metrics.charWidth(content.charAt(i));
}
return width;
}
計算使用字體的最大的高度
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font); int height = metrics.getHeight();
在圖片是寫文字時最合適的位置
Ascent是從基線到頂部最大的高,也可以當做一個種字體畫圖時最有可以點用的高度
graphics.drawString(content, 0, metrics.getAscent());
測試代碼
import sun.font.FontDesignMetrics;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.LineMetrics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Created by zengrenyuan on 18/5/11.
*/
public class ImageTest {
public static void main(String[] args) throws IOException {
Font font = new Font("微軟雅黑", Font.BOLD, 32);
String content = "你好Java!";
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int width = getWordWidth(font, content);//計算圖片的寬
int height = metrics.getHeight();//計算高
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = bufferedImage.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
//設(shè)置背影為白色
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
graphics.setFont(font);
graphics.setColor(Color.BLACK);
graphics.drawString(content, 0, metrics.getAscent());//圖片上寫文字
graphics.dispose();
write(bufferedImage, "/data/test.png");
}
public static int getWordWidth(Font font, String content) {
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int width = 0;
for (int i = 0; i < content.length(); i++) {
width += metrics.charWidth(content.charAt(i));
}
return width;
}
public static void write(BufferedImage bufferedImage, String target) throws IOException {
File file = new File(target);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try (OutputStream os = new FileOutputStream(target)) {
ImageIO.write(bufferedImage, "PNG", os);
}
}
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Java循環(huán)中的For和For-each哪個更快
本文主要介紹了淺談Java循環(huán)中的For和For-each哪個更快,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08

