一、繪製圖形圖像
/**
* 線段 / 折線
*/
public static void drawLine() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
// 抗鋸齒
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 設置畫筆顏色
g2d.setColor(Color.RED);
// 1. 兩點繪製線段: 點(20, 50), 點(200, 50)
g2d.drawLine(50, 50, 200, 50);
// 2. 多點繪製折線: 點(50, 100), 點(100, 130), 點(150, 70), 點(200, 100)
int[] xPoints = new int[] { 50, 100, 150, 200 };
int[] yPoints = new int[] { 100, 120, 80, 100 };
int nPoints = 4;
g2d.drawPolyline(xPoints, yPoints, nPoints);
// 3. 兩點繪製線段(設置線寬爲5px): 點(50, 150), 點(200, 150)
BasicStroke bs1 = new BasicStroke(5); // 筆畫的輪廓(畫筆寬度/線寬爲5px)
g2d.setStroke(bs1);
g2d.drawLine(50, 150, 200, 150);
// 4. 繪製虛線: 將虛線分爲若干段( 實線段 和 空白段 都認爲是一段), 實線段 和 空白段 交替繪製,
// 繪製的每一段(包括 實線段 和 空白段)的 長度 從 dash 虛線模式數組中取值(從首
// 元素開始循環取值), 下面數組即表示每段長度分別爲: 5px, 10px, 5px, 10px, ...
float[] dash = new float[] { 5, 10 };
BasicStroke bs2 = new BasicStroke(
1, // 畫筆寬度/線寬
BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_MITER,
10.0f,
dash, // 虛線模式數組
0.0f
);
g2d.setStroke(bs2);
g2d.drawLine(50, 200, 200, 200);
// 自己創建的副本用完要銷燬掉
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 矩形 / 多邊形
*/
public static void drawRect() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
// 1. 繪製一個矩形: 起點(30, 20), 寬80, 高100
g2d.drawRect(30, 20, 80, 100);
// 2. 填充一個矩形
g2d.fillRect(140, 20, 80, 100);
// 3. 繪製一個圓角矩形: 起點(30, 150), 寬80, 高100, 圓角寬30, 圓角高30
g2d.drawRoundRect(30, 150, 80, 100, 30, 30);
// 4. 繪製一個多邊形(收尾相連): 點(140, 150), 點(180, 250), 點(220, 200)
int[] xPoints = new int[] { 140, 180, 220};
int[] yPoints = new int[] { 150, 250, 200};
int nPoints = 3;
g2d.drawPolygon(xPoints, yPoints, nPoints);
// 繪製一個3D矩形(左上或者右下的邊框高亮實現的3D)
g2d.draw3DRect(300, 300, 80, 80, false);
// 填充一個3D矩形(左上或者右下的邊框高亮實現的3D)
g2d.fill3DRect(400, 400, 80, 80, false);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 圓弧 / 扇形
*/
public static void drawArc() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
// 1. 繪製一條圓弧: 橢圓的外切矩形 左上角座標爲(0, 0), 寬100, 高100,
// 弧的開始角度爲0度, 需要繪製的角度數爲-90度,
// 橢圓右邊水平線爲0度, 逆時針爲正角度, 順時針爲負角度
g2d.drawArc(0, 0, 100, 100, 0, -90);
// 2. 繪製一個圓: 圓的外切矩形 左上角座標爲(120, 20), 寬高爲100
g2d.drawArc(120, 20, 100, 100, 0, 360);
g2d.setColor(Color.GRAY);
// 3. 填充一個扇形
g2d.fillArc(80, 150, 100, 100, 90, 270);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 橢圓 (實際上通過繪製360度的圓弧/扇形也能達到繪製圓/橢圓的效果)
*/
public static void drawOval() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
// 1. 繪製一個圓: 圓的外切矩形 左上角座標爲(0, 0), 寬高爲100
g2d.drawOval(0, 0, 100, 100);
g2d.setColor(Color.GRAY);
// 2. 填充一個橢圓
g2d.fillOval(120, 100, 100, 150);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 文本
*/
public static void drawText() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 設置字體樣式, null 表示使用默認字體, Font.PLAIN 爲普通樣式, 大小爲 25px
g2d.setFont(new Font("楷體", Font.PLAIN, 25));
// 繪製文本, 其中座標參數指的是文本繪製後的 左下角 的位置
// 首次繪製需要初始化字體, 可能需要較耗時
g2d.drawString("Hello World!", 20, 60);
g2d.drawString("你好, 世界!", 20, 120);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 圖片 將一張圖繪成另一張圖
*/
public static void drawImage() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
// 從本地讀取一張圖片
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
// 繪製圖片(如果寬高傳的不是圖片原本的寬高, 則圖片將會適當縮放繪製)
g2d.drawImage(src, 50, 50, 100, 100, null);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
2、修改背景顏色
/**
* 純繪製圖形,默認背景色黑色
*/
public static void drawImageInit() throws IOException{
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
// 獲取Graphics2D
Graphics2D g2d = bi.createGraphics();
// 繪製形狀
g2d.setColor(Color.RED); // 設置填充的顏色 new Color(255, 0, 0)
g2d.fillRect(64, 64, 128, 128); // 填充的矩形,指定開始的x和y,指定矩的w和h
// 釋放對象
g2d.dispose();
FileOutputStream out = new FileOutputStream("F:/Tst/test-res.png");
// 保存文件 方式一 文件更小
ImageIO.write(bi, "png", out);
// 保存文件 方式二 文件更大
ImageEncoder encoder = ImageCodec.createImageEncoder("PNG", out, new PNGEncodeParam.RGB());
encoder.encode(bi);
}
/**
* 純繪製圖形,修改背景色
*/
public static void drawImageChangeBackground() throws IOException{
//創建圖像緩衝區
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
// 獲取Graphics2D
Graphics2D g2d = bi.createGraphics();
// 修改背景色一 默認背景色爲黑色,通過繪製充滿整個圖像緩衝區的填充可以實現修改背景色
g2d.setColor(Color.WHITE); // 設置填充的顏色
g2d.fillRect(0, 0, 256, 256); // 填充的矩形,指定開始的x和y,指定矩的w和h
// 修改背景色二 默認背景色爲黑色,通過設置指定的背景色並使用填充矩形來清除背景色(原理一致)
g2d.setBackground(Color.WHITE); // 指定背景色,不影響當前容器的背景色,僅影響後續的clearRect操作和繪製圖形的默認背景色
g2d.clearRect(0, 0, 256, 256); // 以當前背景色的填充來實現清除指定的矩形
// 繪製圖形
g2d.setColor(Color.RED); // 設置填充的顏色
g2d.fillRect(64, 64, 128, 128); // 填充的矩形,指定開始的x和y,指定矩的w和h
// 釋放對象
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test.png"));
}
/**
* 純繪製圖形,修改背景色爲透明
*/
public static void drawImageChangeTransparent() throws IOException{
//創建圖像緩衝區
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
// 獲取Graphics2D
Graphics2D g2d = bi.createGraphics();
// 設置背景色爲透明
bi = g2d.getDeviceConfiguration().createCompatibleImage(256, 256, Transparency.TRANSLUCENT); // 重新獲取圖片緩衝區
g2d = bi.createGraphics(); // 重新獲取Graphics2D
// 繪製圖形
g2d.setColor(Color.RED); // 設置填充的顏色
g2d.fillRect(64, 64, 128, 128); // 填充的矩形,指定開始的x和y,指定矩的w和h
// 釋放對象
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
3、圖片背景和疊加
/**
* 圖片縮放並添加背景板
*/
public static void resetImageInclude() throws IOException {
// 構造Image對象
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
// 創建和原圖大小一致的容器
BufferedImage res = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
// 將圖片縮小到原來的一半
Image content = src.getScaledInstance(src.getWidth() / 2, src.getHeight() / 2, BufferedImage.TYPE_INT_RGB);
// 填充容器的顏色,即背景顏色
res.getGraphics().setColor(Color.WHITE);
res.getGraphics().fillRect(0, 0, src.getWidth(), src.getHeight());
// 將縮小後的圖片寫入容器的中間位置
res.getGraphics().drawImage(content, src.getWidth() / 4, src.getHeight() / 4, src.getWidth() / 2, src.getHeight() / 2, null);
FileOutputStream out = new FileOutputStream("F:/Tst/test-res.png");
// 保存圖片
ImageEncoder encoder = ImageCodec.createImageEncoder("PNG", out, new PNGEncodeParam.Palette());
encoder.encode(res);
}
/**
* 將一張圖片添加到另一張圖片之上
*/
public static void mergeBothImage() throws IOException {
// 構造Image對象
BufferedImage image = ImageIO.read(new File("F:/Tst/test.png"));
BufferedImage icon = ImageIO.read(new File("F:/Tst/icon.png"));
// 添加
image.getGraphics().drawImage(icon, 100, 100, null);
// 保存
ImageIO.write(image, "PNG", new File("F:/Tst/test-res.png"));
}
/**
* 設置疊加圖片的透明度
*/
public static void clipFillet4() throws IOException {
// 構造Image對象
BufferedImage image = ImageIO.read(new File("F:/Tst/test.png"));
BufferedImage icon = ImageIO.read(new File("F:/Tst/t1.png"));
Graphics2D g2d = image.createGraphics();
// 設置透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f)); // 透明度設置開始(0<alpha<1,0爲透明,1爲不透明)
// 添加
g2d.drawImage(icon, 100, 100, null);
// 結束透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); // 透明度設置 結束
// 再添加
g2d.drawImage(icon, 200, 200, null);
// 保存
ImageIO.write(image, "PNG", new File("F:/Tst/test-res.png"));
}
4、圖片縮放和裁剪
/**
* 縮放 調整大小
* @throws IOException
*/
public static void resetImageSize() throws IOException {
// 構造Image對象
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
// 創建容器
BufferedImage res = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
// 縮放方式一 當指定寬度和高度時將自動進行縮放以填充整個指定範圍的矩形
res.getGraphics().drawImage(src, 0, 0, src.getWidth() / 4, src.getHeight() / 4, null);
// 縮放方式二 原圖縮放後通過畫板寫入
Image content = src.getScaledInstance(src.getWidth() / 2, src.getHeight() / 2, BufferedImage.TYPE_INT_RGB);
// 將內容填充到容器中,不帶寬度和高度時多出部分不顯示(Image不能直接寫入文件)
res.getGraphics().drawImage(content, 0, 0, null);
// 縮放方式三 基於畫板的縮放
Graphics2D g2d = res.createGraphics();
// 縮放畫板
g2d.scale(0.5, 0.5);
// 此時的寬和高如果大於畫板則無效,自動縮放到充滿畫板
g2d.drawImage(src, 0, 0, src.getWidth(), src.getHeight(), null);
// 保存
ImageIO.write(res, "PNG", new File("F:/Tst/test-res.png"));
}
/**
* 限定顯示區域
* @throws IOException
*/
public static void clipRect() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
// 從本地讀取一張圖片
BufferedImage src = ImageIO.read(new File("F:/Tst/yanwo.png"));
// 限定圖形在指定區域內的顯示,超出部分不顯示。多個限制區有覆蓋時,得到限制區域的交集區域
g2d.clipRect(100, 100, 100, 100);
g2d.drawImage(src, 0, 0, src.getWidth(), src.getHeight(), null);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 裁剪圖片
* @throws IOException
*/
public static void subImage() throws IOException {
// 構造圖像緩衝區
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
// 裁剪 起始位置和裁剪大小
BufferedImage res = src.getSubimage(src.getWidth()/4, src.getHeight()/4, src.getWidth()/2, src.getHeight()/2);
// 保存文件
ImageIO.write(res, "PNG", new File("F:/Tst/test-res.png"));
}
4、平移和旋轉
/**
* 平移
*/
public static void translate() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
// 從本地讀取一張圖片
BufferedImage src = ImageIO.read(new File("F:/Tst/yanwo.png"));
// 平移 畫板的平移
g2d.translate(50, 50);
g2d.drawImage(src, 50, 50, src.getWidth() / 2, src.getHeight() / 2, null);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
/**
* 旋轉
*/
public static void rotate() throws IOException {
// 創建圖像緩衝區(空圖片)
BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
// 創建 Graphics 的副本
Graphics2D g2d = bi.createGraphics();
// 從本地讀取一張圖片
BufferedImage src = ImageIO.read(new File("F:/Tst/yanwo.png"));
// 旋轉
g2d.rotate(180, 256, 256);
g2d.drawImage(src, 0, 0, src.getWidth() / 2, src.getHeight() / 2, null);
g2d.dispose();
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
5、圖片水印和灰化
/**
* 在源圖片上設置水印文字
*/
public static void alphaWords2Image() throws IOException {
// 構造Image對象
BufferedImage image = ImageIO.read(new File("F:/Tst/test.png"));
// 創建java2D對象
Graphics2D g2d = image.createGraphics();
// 設置透明度 (0<alpha<1,0爲透明,1爲不透明)
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);
g2d.setComposite(ac);
// 設置文字字體名稱、樣式(Font.PLAIN=標準;Font.BOLD=粗體)、大小
g2d.setFont(new Font("楷體", Font.PLAIN, 22));
g2d.setColor(Color.RED); // 設置字體顏色
// 輸入水印文字及其起始x、y座標
g2d.drawString("僅XXX使用", 100, 80);
g2d.dispose();
FileOutputStream fos = new FileOutputStream("F:/Tst/test-res.png");
ImageIO.write(image, "PNG", fos);
}
/**
* 圖片灰化操作
*/
public static void grayImage() throws IOException {
// 構造Image對象
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
// 定義轉換變量
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); // 顏色空間
ColorConvertOp op = new ColorConvertOp(cs, null); // 顏色轉換
// 執行轉換
src = op.filter(src, null);
// 保存
ImageIO.write(src, "PNG", new File("F:/Tst/test-res.png"));
}
6、水平鏡像
/**
* 水平鏡像圖片
*/
public static void horizontalMirror() throws IOException {
// 讀取圖片
BufferedImage bufImage = ImageIO.read(new File("F:/Tst/test.png"));
// 獲取圖片的寬高
final int width = bufImage.getWidth();
final int height = bufImage.getHeight();
// 讀取出圖片的所有像素
int[] rgbs = bufImage.getRGB(0, 0, width, height, null, 0, width);
// 對圖片的像素矩陣進行水平鏡像
for (int row = 0; row < height; row++) {
for (int col = 0; col < width / 2; col++) {
int temp = rgbs[row * width + col];
rgbs[row * width + col] = rgbs[row * width + (width - 1 - col)];
rgbs[row * width + (width - 1 - col)] = temp;
}
}
// 把水平鏡像後的像素矩陣設置回 bufImage
bufImage.setRGB(0, 0, width, height, rgbs, 0, width);
// 把修改過的 bufImage 保存到本地
ImageIO.write(bufImage, "PNG", new File("F:/Tst/test-res.png"));
}
7、切透明圓角
/**
* 圖片切圓角一 切除部分透明
*/
public static void clipFillet() throws IOException {
// 構造Image對象
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
// ARGB從表面看比RGB多了個A,也是一種色彩模式,是在RGB的基礎上添加了Alpha(透明度)通道
BufferedImage image = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D gs = image.createGraphics();
gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gs.setClip(new RoundRectangle2D.Double(0, 0, src.getWidth(), src.getHeight(), src.getWidth()/5, src.getHeight()/5));
gs.drawImage(src, 0, 0, src.getWidth(), src.getHeight(), null);
gs.dispose();
ImageIO.write(image, "png", new File("F:/Tst/test-res.png"));
}
/**
* 圖片切圓角二 切除部分透明
* @throws IOException
*/
public static void clipFillet() throws IOException {
// 構造Image對象
BufferedImage src = ImageIO.read(new File("F:/Tst/test.png"));
BufferedImage image = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D gs = image.createGraphics();
// 設置背景色爲透明
image = gs.getDeviceConfiguration().createCompatibleImage(src.getWidth(), src.getHeight(), Transparency.TRANSLUCENT); // 重新獲取圖片緩衝區
gs = image.createGraphics(); // 重新獲取Graphics2D
gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gs.setClip(new RoundRectangle2D.Double(0, 0, src.getWidth(), src.getHeight(), src.getWidth()/5, src.getHeight()/5));
gs.drawImage(src, 0, 0, src.getWidth(), src.getHeight(), null);
gs.dispose();
ImageIO.write(image, "png", new File("F:/Tst/test-res.png"));
}
8、圖片RGB值的讀寫
/**
* 獲取RGB的值
*/
public static void getRGB() throws IOException {
//讀入文件
File file = new File("F:/Tst/test.png");
// 構造Image對象
BufferedImage src = ImageIO.read(file);
// 獲取指定座標的RGB值
System.out.println(src.getRGB(400, 200));
// 獲取指定區域的RGB值 從指定起點到指定寬度和高度的區域的RGB數組,offset表示數組開頭的偏移,scansize表示一行佔用的長度(可以大於指定寬度,但小於時異常)
System.out.println(src.getRGB(400, 200, 100, 100, null, 0, 100));
}
/**
* 設置RGB的值
*/
public static void setRGB() throws IOException {
//創建圖像緩衝區
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
// 獲取Graphics2D
Graphics2D g2d = bi.createGraphics();
// 初始化
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, 256, 256);
// 設置指定座標的RGB值
bi.setRGB(80, 80, 10000);
// 設置從指定起點到指定寬度和高度的區域的RGB值,offset表示數組開頭的偏移,scansize表示一行佔用的長度
bi.setRGB(120, 120, 16, 16, new int[256], 0, 16);
// 保存文件
ImageIO.write(bi, "png", new File("F:/Tst/test-res.png"));
}
9、圖片轉TIF格式
/**
* PNG轉TIF 通過JAI包實現 JPG等類似
* @throws IOException
*/
public static void pngToTif() throws IOException {
// 創建操作對象
RenderedOp renderOp = JAI.create("fileload", "F:/Tst/test.png");
// 創建存儲文件流
OutputStream outputStream = new FileOutputStream("F:/Tst/test.tif");
// 創建編碼器
TIFFEncodeParam tiffParam = new TIFFEncodeParam();
ImageEncoder imageEncoder = ImageCodec.createImageEncoder("TIFF", outputStream, tiffParam);
// 轉換保存
imageEncoder.encode(renderOp);
}