《Java数字图像处理:编程技巧与应用实践》——1.4 Swing Java 2D的其他高级特性介绍

1.4 Swing Java 2D的其他高级特性介绍

1 . Stroke接口

Stroke是Graphics2D的API接口,用来实现图形的描边修饰,在Java 2D中只有一个完成Stroke接口的类BasicStroke,如果有需要,可以自己完成Stroke接口,实现自定义的Stroke类。如何使用Stroke的实现类?方法如下:

1)调用Graphics2D 的setStroke()方法,传入一个实例化的Stroke对象。
2)调用draw()方法,传入要绘制的几何形状。

BasicStroke的对象构造函数代码如下:

// 创建Stroke对象实例
float[] dash = {10.0f, 5.0f, 3.0f};
Stroke dashed = new BasicStroke(2.0f, BasicStroke.CAP_BUTT,
    BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);

其中:

  • 第一个参数2.0f表示Stroke的宽度。
  • 第二个参数声明Stoke的结束方式,BasicStroke.CAP_BUTT表示如果不是闭合区域则不做任何修饰,直接结束绘制,BasicStroke.CAP_ROUND表示如果不是闭合则添加圆角帽线,然后结束。
  • 第三个参数表示线的连接方式,此处为JOIN_MITER。
  • 第四个参数指定Stoke线段的长度,此处线段长度为10。
  • 第五个参数声明点线模式,此处点线模式dash为不等长线段。
  • 第六个参数声明位移,0.0表示位移间隔为零。

更详细的参数说明可以参考JDK的官方文档,下面的代码通过创建BasicStroke实例对象来绘制一个虚线矩形:

// 创建Stroke对象实例
float[] dash = {10.0f, 5.0f, 3.0f};
Stroke dashed = new BasicStroke(2.0f, BasicStroke.CAP_SQUARE,
            BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);

// 设置Graphics2D的Stroke对象引用
g2.setStroke(dashed);

// 创建形状
Shape rect2D = new RoundRectangle2D.Double(50, 50,
                    300, 100, 10, 10);
g2.draw(rect2D);

2 . Texture Fill接口

Texture Fill即纹理填充,Graphics2D提供了setPaint()方法来设置纹理填充,通过fill()方法可实现对几何形状的填充。前面讲到的两种填充方式分别为颜色填充与渐变填充,这里将重点介绍纹理填充的类TexturePaint创建与使用。

TexturePaint通过构造一个BufferedImage对象作为纹理来填充几何形状,因为Buffered-Image对象数据将被拷贝到TexturePaint中,所以BufferedImage对象设置得比较小为好。实例化一个TexturePaint对象的代码如下:

Rectangle2D rect = new Rectangle2D.Double(10,10,200,200);
TexturePaint tp = new TexturePaint(image, rect)

其中image表示一个BufferedImage实例,rect表示截取作为纹理的区域。
使用实例化的TexturePaint来完成对矩形区域填充的代码如下:

// Texture Fill
Rectangle2D rect = new Rectangle2D.Double(10,10,200,200);
TexturePaint tp = new TexturePaint(image, rect);
g2.setPaint(tp);
g2.fill(rect2D);

3 . Font属性

Java 2D支持绝大多数常见字体的创建与属性值的修改调整,可通过Graphics2D setFont()方法来实现绘制字体的修改,同时Graphics2D绘制引擎还支持自定义的外部字体文件*.ttf的动态加载与使用。只要在使用之前加载字体文件即可,使用下面的代码可实现字体文件加载:

public Font loadFont() throws FontFormatException, IOException
{
    String fontFileName = "AMERSN.ttf";
    InputStream is = this.getClass().
            getResourceAsStream(fontFileName);
    Font actionJson = Font.createFont(Font.TRUETYPE_FONT, is);
    Font actionJsonBase = actionJson.deriveFont(Font.BOLD, 16);
    return actionJsonBase;
}

字体加载与使用的完整代码如下:

package com.book.chapter.one;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class FontDemo extends JPanel {

private static final long serialVersionUID = 1L;

public FontDemo() {
        super();
}

public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    // 反锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    // 设置画笔颜色
    g2d.setPaint(Color.BLUE);
    try {
        g2d.setFont(loadFont());
    } catch (FontFormatException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    g2d.drawString("Font Demo", 50, 50);
    g2d.dispose(); // 释放资源
}

public Font loadFont() throws FontFormatException,
IOException {
    String fontFileName = "AMERSN.ttf";
    InputStream is = this.getClass().
        getResourceAsStream(fontFileName);
    Font actionJson = Font.createFont(
            Font.TRUETYPE_FONT, is);
    Font actionJsonBase =
        actionJson.deriveFont(Font.BOLD, 16);
    return actionJsonBase;
}

public static void main(String[] args) {
    JFrame ui = new JFrame("Font Demo Graphics2D");
    ui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ui.getContentPane().setLayout(new BorderLayout());
    ui.getContentPane().add(new FontDemo(),
        BorderLayout.CENTER);
    ui.setPreferredSize(new Dimension(380, 380));
    ui.pack();
        ui.setVisible(true);
    }
}

4 . GeneralPath与自定义几何形状

Java 2D支持通过GeneralPath实现绘制任意的几何形状,使用GeneralPath提供的API接口绘制几何形状的步骤大致如下:

1)实例化GeneralPath对象。
2)调用moveTo()方法锚地开始点坐标。
3)调用lineTo()或curveTo方法绘制连接线。
4)调用closePath()方法完成几何形状绘制。

下面的代码实现了利用GeneralPath对象绘制一个红色五角星图案。

package com.book.chapter.one;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class GeneralPathDemo extends JPanel {
    /**
    *
    */
    private static final long serialVersionUID = 1L;

    public GeneralPathDemo() {
        super();
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        // 反锯齿
        g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        // 五角星的五个点坐标
        int x1 = this.getWidth() / 2;
        int y1 = 20;
        int x2 = this.getWidth() / 5;
        int y2 = this.getHeight() - 20;
        int x3 = x2 * 4;
        int y3 = this.getHeight() - 20;
        int x4 = 20;
        int y4 = this.getHeight() / 3;
        int x5 = this.getWidth() - 20;
        int y5 = y4;

        // 定义画点的顺序
        int x1Points[] = { x1, x2, x5, x4, x3 };
        int y1Points[] = { y1, y2, y5, y4, y3 };

        // 设置填充颜色
        g2d.setPaint(Color.RED);

        // 实例化GeneralPath对象
        GeneralPath polygon = new GeneralPath(
                GeneralPath.WIND_EVEN_ODD,
                x1Points.length);
        // 锚地开始第一个点
        polygon.moveTo(x1Points[0], y1Points[0]);
        // 顺序画出剩下点
        for (int i = 1; i < x1Points.length; i++) {
            polygon.lineTo(x1Points[i], y1Points[i]);
        }

        // 调用closePath形成一个封闭几何形状
        polygon.closePath();

        // 绘制它
        g2d.draw(polygon);

        // 释放资源
        g2d.dispose();
    }

    public static void main(String[] args) {
        JFrame ui = new JFrame("Demo Graphics");
        ui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ui.getContentPane().setLayout(new BorderLayout());
        ui.getContentPane().add(new GeneralPathDemo(),
                    BorderLayout.CENTER);
        ui.setPreferredSize(new Dimension(380, 380));
        ui.pack();
        ui.setVisible(true);
    }

}
时间: 2024-09-09 13:25:32

《Java数字图像处理:编程技巧与应用实践》——1.4 Swing Java 2D的其他高级特性介绍的相关文章

《Java数字图像处理:编程技巧与应用实践》——导读

前 言 为什么要写这本书 我对图像处理的认识最初来自于读软件工程专业时做毕业设计论文的需要,毕业论文做完以后,我便把所有关于图像处理的知识扔到了一边.2011年的一天有位朋友问了我几个简单的图像处理方面的问题,在解答问题的过程中我发现自己对图像处理的热情一直都在燃烧,从那一刻起我决定重新学习图像处理.这之后,我把以前买的几本图像处理的书都读了一遍,同时还坚持通过写博客来督促自己加深理解,随着学习的不断深入,对图像处理的认知也在不断加深,我越来越渴望自己能实现那些书中提到的图像处理手段与方法,于是

《Java数字图像处理:编程技巧与应用实践》——第3章 基本Swing UI组件与图像显示 3.1 JPanel组件与BufferedImage对象的显示

第3章 基本Swing UI组件与图像显示 上一章介绍了BufferedImageOp的一些重要知识,实现了几个常见的图像特效,本章介绍如何通过Swing UI组件显示与刷新图像.首先会介绍JAVA Swing的顶层组件JFrame,然后介绍Swing中最重要和使用频率最高的组件JPanel,教会读者重写JComponent中的paintComponent()方法来实现图像的显示,最后会介绍Swing组件JButton捕获与监听用户行为时最重要的ActionListener接口的使用,以及在Sw

《Java数字图像处理:编程技巧与应用实践》——第2章 Java BufferedImage对象及其支持的API操作 2.1 BufferedImage对象的构成

第2章 Java BufferedImage对象及其支持的API操作 第1章我们一起学习了Java中的Graphics图形包基本概念与知识,本章将介绍Java中关于图像文件操作的基本知识.首先是Java 2D图像对象BufferedImage的组件构成.与图像文件之间的关系.格式支持,以及如何利用BufferedImage对象在Java语言中实现像素读写操作.然后通过BufferedImageOp接口介绍Java中几种非常有用的对像素操作的Buffered-ImageOp的实现类.最后将集合上述

《Java数字图像处理:编程技巧与应用实践》——2.4 小结

2.4 小结 本章重点介绍了Java 2D中关于图像方面的操作接口类BufferedImageOp,通过其实现类可以很方便地实现图像的色彩空间转换,自定义颜色查找表,卷积功能(包括边缘提取.线性模糊.高斯模糊),图像的放大与缩小.错切变化.平移变换.旋转变换等.最后本章通过编码实现了几种简单而且常见的图像处理功能,帮助读者加深对BufferedImageOp接口的认识.如果你还想更加深入地了解BufferedImageOp接口实现类的使用,请参照JDK官方文档说明,同时建议你多多编程实践,只有加

《Java数字图像处理:编程技巧与应用实践》——2.3 基于BufferedImageOp的图像滤镜演示

2.3 基于BufferedImageOp的图像滤镜演示 通过前面两节的学习,我们已经大致了解BufferedImageOp接口及其实现类的功能.实践出真知,本节将演示BufferedImageOp接口中每个实现类的实际使用场景,达到知行合一.学以致用的目的,帮助大家解决项目中遇到的实际问题.为了让大家对应用效果有更加深刻的印象,下面会使用BufferedImageOp的实现类来实现如下几个滤镜特效功能. 黑白滤镜:将彩色图像自动转换为黑白两色图像. 灰度滤镜:将彩色图像自动转换为灰度图像. 模

《Java数字图像处理:编程技巧与应用实践》——第1章 Java Graphics及其API简介 1.1 什么是Java图形设备Graphics

第1章 Java Graphics及其API简介 在开始本书内容之前,笔者假设你已经有了面向对象语言编程的基本概念,了解Java语言的基本语法与特征,原因在于本书的所有源代码都是基于Java语言实现的,而且是基于Java开发环境运行与演示所有图像处理算法的.本书第1章到第3章是为了帮助读者了解与掌握Java 图形与GUI编程的基本知识与概念而写的.本章主要介绍Java GUI编程中基本的图形知识,针对GUI编程,Java语言提供了两套几乎并行的API,分别是Swing与AWT.早期的Java G

《Java数字图像处理:编程技巧与应用实践》——3.6 小结

3.6 小结 本章一步一步地剖析如何了构建一个Swing UI程序,介绍了JPanel.JButton.JFile-Chooser等组件的用法,最后通过JFrame组件组合成为用户交互界面,实现了对图像文件的显示与操作,以及UI响应用户的操作与刷新.这也是本书后面多数章节中要用到的测试UI,所以学习与掌握本章知识,将为后面图像处理的代码提供一个UI现实与效果演示界面,帮助读者加深对知识的理解.前面三章已经介绍了Java图像处理API基础知识与Swing的基础知识,这为后面学习图像处理做了很好的铺

《Java数字图像处理:编程技巧与应用实践》——1.3 用Java Swing绘制自定义的JPanel

1.3 用Java Swing绘制自定义的JPanel Swing的JPanel组件是GUI编程中最重要的面板组件,可以通过重写JPanel中paint-Component方法实现对JPanel面板组件的背景颜色的调整或添加背景图片,进而实现自定义版本的面板(JPanel)组件.只要完成如下几步就可以实现一个简单自定义JPanel面板的绘制. 1)实现对JPanel面板的继承,代码如下: public class CustomJPanel extends JPanel { // 更多代码 } 2

《Java数字图像处理:编程技巧与应用实践》——3.4 基本JButton事件响应

3.4 基本JButton事件响应 在学习JButton事件响应的知识之前,首先来看一下Swing中如何实现对用户事件的监听与处理,认识一下Swing中事件响应最重要的线程-事件分派线程. 在Swing中有一个特殊的线程被称为Swing事件分配线程,如果对UI组件的操作不在Swing事件分派线程中,Swing将抛出异常.检测当前线程是否为事件分派线程可以通过Swing本身提供的一个简单方法SwingUtilities.isEventDispatchThread()来完成.对Swing UI组件的