Java图像编程之:Graphics2D

一、介绍

1、Java图像编程的核心类

  1. BufferedImage:用于表示图像的类,可以进行像素级的操作。
  2. Image:表示图像的抽象类,是所有图像类的基类。
  3. ImageIcon:用于显示图像的类,可以将图像嵌入到Swing组件中。
  4. ImageIO:用于读取和写入图像文件的类。
  5. Graphics:用于进行图像绘制操作的抽象类,可以绘制直线、矩形、椭圆等图形。
  6. Graphics2D:继承自Graphics类,提供了更多的绘制方法和功能,可以进行更高级的图像绘制操作。
  7. Color:用于表示颜色的类,可以设置图像的颜色。
  8. Font:用于表示字体的类,可以设置图像的字体样式。

2、Graphics2D介绍

java.awt.Graphics2D 是 Java 编程语言中的一个类,它是java.awt.Graphics类的子类。它提供了一系列用于绘制图形和处理图形操作的方法。Graphics2D 类是 Java 2D API 的一部分,它允许开发人员在图形界面应用程序中创建复杂的图形和图像效果。

Graphics2D 类提供了一些强大的绘图功能,如绘制线条、矩形、椭圆、多边形等。它还支持图像的平移、旋转、缩放和剪切等变换操作。此外,Graphics2D 还可以设置绘图属性,如颜色、字体和渐变等,以实现更丰富的图形效果。

要使用 Graphics2D 类,您需要先创建一个 Graphics2D 对象。通常,您可以通过调用 java.awt.Graphics 类的 create 方法来获取 Graphics2D 对象。一旦获取了 Graphics2D 对象,您就可以使用它的方法来绘制和操作图形。

例如,您可以使用 Graphics2D 的 drawLine 方法绘制一条直线,使用 drawRect 方法绘制一个矩形,使用 drawOval 方法绘制一个椭圆等等。除了基本形状,您还可以使用 Graphics2D 的 fill 方法来填充图形内部,以创建实心的图形效果。

Graphics2D 类还支持文本绘制功能。您可以使用 drawString 方法在图形上绘制文本,并通过设置字体、颜色等属性来调整文本的外观。

总之,Graphics2D 类提供了丰富的图形绘制和操作功能,使开发人员能够创建各种各样的图形效果。无论是绘制简单的图形还是实现复杂的图像处理,Graphics2D 都是一个强大而灵活的工具。

3、Graphics2D 和 Graphics的区别

java.awt.Graphics2D 和 java.awt.Graphics 是 Java AWT(Abstract Window Toolkit)中用于图形绘制的两个类,它们之间有以下区别:

  1. 继承关系: java.awt.Graphics2D 是 java.awt.Graphics 的子类。因此,Graphics2D 继承了 Graphics 类的所有方法,并且还添加了一些额外的方法和功能。

  2. 功能和方法:

    • java.awt.Graphics 提供了一些基本的绘图方法,如绘制线条、矩形、椭圆等。它的方法相对较少,功能相对有限。
    • java.awt.Graphics2D 是 Graphics 类的扩展,提供了更多的绘图功能和方法。它支持更复杂的图形操作,如图形变换(平移、旋转、缩放和剪切)、设置绘图属性(颜色、字体、渐变等)以及绘制复杂的图形效果(如渐变填充、阴影效果等)。此外,Graphics2D 还支持文本绘制功能。
    • 对象获取:

      • 对于 Graphics 类,可以通过组件的 paint 方法中的参数获取 Graphics 对象,如 paint(Graphics g)。
      • 要获取 Graphics2D 对象,通常可以通过强制类型转换将 Graphics 对象转换为 Graphics2D 对象,如 Graphics2D g2d = (Graphics2D) g。
      • 用途:

        • Graphics 类主要用于简单的图形绘制,适用于一些简单的绘图需求。
        • Graphics2D 类提供了更强大和灵活的绘图功能,适用于需要进行复杂图形操作和绘制高级图形效果的场景。

综上所述,java.awt.Graphics2D 是对 java.awt.Graphics 的扩展,提供了更多的绘图功能和方法,使开发人员能够创建更复杂、更丰富的图形效果。在需要进行复杂图形操作和绘制高级图形效果的情况下,推荐使用 Graphics2D 类。

4、和Graphics2D配套使用的类

Graphics2D 类是 Java 2D API 中的核心类,它提供了丰富的图形绘制和操作功能。下面是一些与 Graphics2D 配套使用的主要类:

  1. java.awt.Color:用于表示颜色,可以通过 Graphics2D 的 setColor 方法设置绘图颜色。
  2. java.awt.Font:用于表示字体,可以通过 Graphics2D 的 setFont 方法设置绘图字体。
  3. java.awt.Stroke:用于表示线条样式,可以通过 Graphics2D 的 setStroke 方法设置绘图线条样式。
  4. java.awt.GradientPaint:用于表示渐变颜色,可以创建渐变效果的绘图颜色。
  5. java.awt.TexturePaint:用于表示纹理颜色,可以使用纹理图像作为绘图颜色。
  6. java.awt.Shape:用于表示图形形状,如线条、矩形、椭圆等。Graphics2D 的绘图方法通常会接受 Shape 对象作为参数进行绘制。
  7. java.awt.image.BufferedImage:用于表示图像,可以通过 Graphics2D 的 drawImage 方法绘制图像。
  8. java.awt.geom 包:提供了一系列几何形状类,如 Line2D、Rectangle2D、Ellipse2D (都是Shape子类)等,可以与 Graphics2D 配合使用来绘制更复杂的图形。
  9. java.awt.font 包:提供了字体相关的类,如 FontRenderContext、GlyphVector 等,可以用于绘制文本和处理字体渲染。

这些类是 Graphics2D 的配套类,可以与 Graphics2D 一起使用来实现各种各样的图形绘制和效果。通过组合使用这些类,您可以创建出丰富多样的图形界面应用程序。

java.awt.Shape 主要有以下子类:

子类中文说明
java.awt.Rectangle矩形
java.awt.Polygon多边形
java.awt.Ellipse椭圆
java.awt.Arc
java.awt.Line2D直线
java.awt.CubicCurve2D三次贝塞尔曲线
java.awt.QuadCurve2D二次贝塞尔曲线
java.awt.Arc2D弧形
java.awt.Area区域
java.awt.Path2D路径
java.awt.geom.RoundRectangle2D圆角矩形
java.awt.geom.GeneralPath通用路径
java.awt.geom.PathIterator路径迭代器
java.awt.geom.FlatteningPathIterator平坦化路径迭代器
java.awt.font.TextLayout文本布局
java.awt.font.GlyphVector字形向量
java.awt.font.ShapeGraphicAttribute形状图形属性

5、java.awt.Graphics2D的核心方法

下表列出了 java.awt.Graphics2D 类的一些主要方法及其功能:

方法名称功能描述
void draw(Shape s)绘制指定形状的轮廓
void fill(Shape s)填充指定形状的区域
void drawString(String str, int x, int y)在给定坐标位置绘制指定字符串
void setPaint(Paint paint)设置绘图用的颜色或渐变
void setStroke(Stroke s)设置绘图用的线条样式
void setFont(Font font)设置绘图用的字体
void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)设置绘图渲染提示,如抗锯齿、图像质量等
void translate(int x, int y)将坐标系统平移指定的距离
void rotate(double theta)将坐标系统旋转指定的角度
void scale(double sx, double sy)将坐标系统按指定的比例缩放
void clip(Shape s)设置绘图剪切区域,只有在剪切区域内的图形才会被绘制
void drawImage(Image img, int x, int y, ImageObserver observer)绘制指定图像到指定坐标位置

二、代码示例

以下通过示例代码,演示几个主要的方法使用。

注意:原点坐标是左上角,x轴向右增加,y轴向下增加

ImageUtil工具类

public class ImageUtil { public static BufferedImage createImage() { int imageWidth = 500;
        int imageHeight = 500;
        return new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
    }
    /**
     * 将图片保存到指定位置
     */
    public static void saveImage2File(BufferedImage image, String fileLocation, String fileName) { try { File file = new File(fileLocation);
            if (!file.exists()) { file.mkdir();
            }
            FileOutputStream fos = new FileOutputStream(fileLocation + fileName);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            ImageIO.write(image, "png", fos);
            bos.close();
        } catch (Exception e) { e.printStackTrace();
        }
    }
}

1、常用示例

 public static void test() { BufferedImage bufferedImage = ImageUtil.createImage();
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        //抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //高质量
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        //设置浅灰色,并绘制背景
        g.setColor(new Color(0XEEEEEE));
        g.fillRect(0,0,500,500);
        //设置笔画
        BasicStroke stroke = new BasicStroke(10);
        g.setStroke(stroke);
        g.setColor(Color.pink);
        //画线
        Line2D line = new Line2D.Float(0, 0, 200, 300);
        g.draw(line);
        //设置渐变填充
        GradientPaint gt = new GradientPaint(0, 0, Color.green, 50, 30, Color.blue, true);
        g.setPaint(gt);
        //画矩形
        Rectangle2D rect = new Rectangle2D.Float(80, 80, 100, 100);
        g.draw(rect);
        g.setColor(Color.pink);
        // 填充矩形
        rect = new Rectangle2D.Float(275, 275, 50, 50);
        g.fill(rect);
        //画椭圆
        Ellipse2D ellipse = new Ellipse2D.Float(120, 120, 100, 120);
        g.draw(ellipse);
        // 设置渐变色
        gt = new GradientPaint(0, 0, Color.red, 30, 30, Color.yellow, true);
        g.setPaint(gt);
        // 画圆
        ellipse = new Ellipse2D.Float(240, 240, 120, 120);
        g.draw(ellipse);
        ImageUtil.saveImage2File(bufferedImage, "d:/temp/image/", "g2d_001.png");
    }

2、绘制圆弧

 /**
     * 圆弧
     */
    public static void arc2D() { BufferedImage bufferedImage = ImageUtil.createImage();
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        //抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //高质量
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        //设置浅灰色,并绘制背景
        g.setColor(new Color(0XEEEEEE));
        g.fillRect(0,0,500,500);
        //设置笔画
        BasicStroke stroke = new BasicStroke(5);
        g.setStroke(stroke);
        g.setColor(Color.pink);
        // x、y 绘制的左上角坐标,w、h 宽、高,start 开始的角度,extent 绘制的总角度,绘制角度从右到左计算
        // type 可选值:Arc2D.OPEN 开放,Arc2D.CHORD 闭合,Arc2D.PIE 饼图
        Arc2D arc1 = new Arc2D.Double(100, 20, 100, 100, 5, 180, Arc2D.OPEN);
        g.draw(arc1);
        g.setColor(Color.green);
        Arc2D arc2 = new Arc2D.Double(100, 120, 100, 100, 0, 180, Arc2D.CHORD);
        g.draw(arc2);
        g.setColor(Color.blue);
        Arc2D arc3 = new Arc2D.Double(100, 180, 100, 100, 0, 270, Arc2D.PIE);
        g.draw(arc3);
        g.setColor(Color.orange);
        arc3 = new Arc2D.Double(100, 300, 100, 100, 0, 270, Arc2D.CHORD);
        g.draw(arc3);
        ImageUtil.saveImage2File(bufferedImage, "d:/temp/image/", "arc.png");
    }

3、绘制曲线

 public static void curver2D() { BufferedImage bufferedImage = ImageUtil.createImage();
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        //抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //高质量
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        //设置浅灰色,并绘制背景
        g.setColor(new Color(0XEEEEEE));
        g.fillRect(0,0,500,500);
        //设置笔画
        BasicStroke stroke = new BasicStroke(5);
        g.setStroke(stroke);
        // 二次曲线
        // x1,y1 起点坐标,ctrlx X轴控制点,ctrly Y轴控制点,x2,y2 终点坐标,
        QuadCurve2D q1 = new QuadCurve2D.Double(20,20,100,100,200,20);
        QuadCurve2D q2 = new QuadCurve2D.Double(20,30,100,100,30,200);
        g.setColor(Color.pink);
        g.draw(q1);
        g.draw(q2);
        // 三次曲线
        CubicCurve2D c1 = new CubicCurve2D.Double(50, 200, 150, 100, 200, 300, 300, 200);
        CubicCurve2D c2 = new CubicCurve2D.Double(300, 220, 200, 300, 400, 400, 300, 450);
        g.setColor(Color.green);
        g.draw(c1);
        g.draw(c2);
        ImageUtil.saveImage2File(bufferedImage, "d:/temp/image/", "curver2D.png");
    }

4、绘制通用路径

 /**
     * 通用路径
     */
    public static void generalPath() { BufferedImage bufferedImage = ImageUtil.createImage();
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        //抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //高质量
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        //设置浅灰色,并绘制背景
        g.setColor(new Color(0XEEEEEE));
        g.fillRect(0,0,500,500);
        //设置笔画
        BasicStroke stroke = new BasicStroke(10);
        g.setStroke(stroke);
        g.setColor(Color.pink);
        //画几何图形
        GeneralPath path = new GeneralPath();
        // 移动坐标到 150,0
        path.moveTo(150, 0);
        // 画线到 150,150
        path.lineTo(150,150);
        // 画曲线,三点链接,
        path.curveTo(250, 150, 300, 200, 150, 300);
        // 画曲线,三点链接,
        path.curveTo(50, 350, 150, 400, 250, 450);
        g.draw(path);
        ImageUtil.saveImage2File(bufferedImage, "d:/temp/image/", "generalPath.png");
    }

5、绘制文本

 public static void text() { BufferedImage bufferedImage = ImageUtil.createImage();
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        //抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //高质量
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        //设置浅灰色,并绘制背景
        g.setColor(new Color(0XEEEEEE));
        g.fillRect(0, 0, 500, 500);
        //设置笔画
        BasicStroke stroke = new BasicStroke(2);
        g.setStroke(stroke);
        g.setColor(Color.pink);
        FontRenderContext frc = g.getFontRenderContext();
        //设置字体
        Font font1 = new Font("黑体", Font.BOLD, 36);
        String str = "文本绘制标题测试";
        //构造文本布局
        TextLayout layout = new TextLayout(str, font1, frc);
        Point2D loc = new Point2D.Float(20, 50);
        //绘制文本
        layout.draw(g, (float) loc.getX(), (float) loc.getY());
        //设置边框
        Rectangle2D bounds = layout.getBounds();
        bounds.setRect(bounds.getX() + loc.getX(),
                bounds.getY() + loc.getY(),
                bounds.getWidth(),
                bounds.getHeight());
        g.draw(bounds);
        //绘制另一行文字
        Font font2 = new Font("微软雅黑", Font.BOLD, 24);
        String str2 = "文本绘制子标题Java图像";
        TextLayout layout2 = new TextLayout(str2, font2, frc);
        g.setColor(Color.gray);
        layout2.draw(g, 20, 180);
        ImageUtil.saveImage2File(bufferedImage, "d:/temp/image/", "text.png");
    }