java绘图(基于Graphics2D)

摘要:
D、 调用Graphics2D对象的dispose()方法执行绘图处理,以便将绘图效果应用于BufferedImage对象。e、 使用ImageIO类的write函数将图像对象转换为文件或二进制流是使用java绘图的基本过程,步骤c涉及许多绘图细节。如下图所示,对于文本的绘图示例,java提供了

1.绘图基本操作

请参考下面基础示例:

 1         int width = 200, height = 250;
 2         //创建图片对象
 3         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
 4         //基于图片对象打开绘图
 5         Graphics2D graphics = image.createGraphics();
 6         //绘图逻辑 START (基于业务逻辑进行绘图处理)……
 7 
 8         //绘制圆形
 9         graphics.setColor(Color.BLACK);
10         Ellipse2D.Double ellipse = new Ellipse2D.Double(20, 20, 100, 100);
11         graphics.draw(ellipse);
12 
13         // 绘图逻辑 END
14         //处理绘图
15         graphics.dispose();
16         //将绘制好的图片写入到图片
17         ImageIO.write(image, "png", new File("abc.png"));

如上代码所示,使用java绘图基本操作流程如下:

  a.得到一个 BufferedImage ,可以是直接指定分辨率new一个空图片,也

  b.基于此BufferedImage 创建一个绘图对象,使用 createGraphics 方法,得 Graphics2D 实例

  c.使用Graphics2D 实例进行画图,所有绘图坐标基于创建此Graphics2D 的BufferedImage。示例中在图片上画了一个圆形。

  d.调用Graphics2D 对象的 dispose() 方法,进行绘图处理,使绘图效果应用到BufferedImage 对象

  e.使用ImageIO类的write函数将图片对象转换到文件或二进制流

上面是使用java进行绘图的基本流程,其中步骤c涉及到很多绘图细节。下面总结一些常用绘图操作:

限制绘图区域

如果绘图时,只希望指定范围内的区域绘图生效,其他区域不受影响,我们可以使用 setClip 函数Shape区域对象作为参数设置剪辑区域

            Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, diameter, diameter);
            Graphics2D graphics = formatAvatarImage.createGraphics();
            //设置剪辑区域,范围外的区域不受绘图影响。这里指定圆形区域作为绘制区域
            graphics.setClip(shape);
            // 将另一张图片绘制到图像中,
            graphics.drawImage(avatarImage, (diameter - width + circleW) / 2, (diameter - height + circleW) / 2, null);
            graphics.dispose();

图形的原点坐标:

 由于绘制图形时,所有绘制都基于坐标进行绘制,所以绘制之前必须了解图形的原点坐标,才能将图形绘制到准确的位置

  1.方形:方形的原点坐标位于左上角(图片本身都是方形,因此在图像中绘制另一张图片时,图片的原点坐标也在左上角)

  2.椭圆形: 椭圆形的原点坐标位于圆心

  3.文字:文字的原点坐标位于左侧与基线的交点上(参考后面绘制文字)

绘制图片

  图片绘制主要分三步

  1.将图片转换为BufferedImage 对象

  2.计算绘制位置

  3.进行绘制

1         //将图片转换为BufferedImage对象
2         BufferedImage bufferedImage = ImageIO.read(new File("C:\Users\minggliu\Pictures\test\test.png"));
3         //计算绘制位置
4         int x = 0, y = 0;
5         //执行绘制
6         //graphics.drawImage(bufferedImage.getScaledInstance(imageW, imageH, Image.SCALE_DEFAULT),100, 100, null);
7         //graphics.drawImage(bufferedImage, 0, 0, width / 2, height / 2, null);
8         graphics.drawImage(bufferedImage, x, y, null);

注意到上面执行绘制注释了上面两种,

 a.使用

graphics.drawImage(bufferedImage, x, y, null);
绘制图片不会进行resize

b.使用
graphics.drawImage(bufferedImage, 0, 0, width / 2, height / 2, null);
绘制图片,系统会将图片resize到 width / 2, height / 2 大小

c.使用
graphics.drawImage(bufferedImage.getScaledInstance(imageW, imageH, Image.SCALE_DEFAULT),100, 100, null);

 绘制图片则先进行了resize,再画到对应的位置,结果与b相同,不过预先的resize有更多的功能,可以指定resize方式

对于一些特殊resize要求,需要走代码逻辑进行特殊处理,下面给出常用resize方式:

以图形中间为原点进行无压缩裁剪resize:

    public static BufferedImage resize(BufferedImage image, int needW, int needH) {
        int resizeW, resizeH, resizeX, resizeY;
        int imgW = image.getWidth(), imgH = image.getHeight();
        int wantH = imgW * needH / needW;
        //如果图片属于过方形
        if (wantH < imgH) {
            resizeH = imgW * needH / needW;
            resizeW = imgW;
            resizeX = 0;
            resizeY = (imgH - wantH) / 2;
        }
        //图片属于过长形
        else {
            resizeH = imgH;
            resizeW = imgH * needW / needH;
            resizeX = (imgW - imgH * needW / needH) / 2;
            resizeY = 0;
        }
        return image.getSubimage(resizeX, resizeY, resizeW, resizeH);
    }

绘制文字

1.绘制文字需要指定字体,同时需要系统运行的系统上安装了对应字体

安装:

 a.将字体文件存放到字体目录

/usr/share/fonts

b.刷新字体信息
sudo mkfontscale  #生成核心字体信息
sudo mkfontdir
sudo fc-cache -fv

c.重启进程

3.文本框的坐标定位

  文字的原点坐标不同于一般图形在右上角,如果需要将文字准确的绘制到指定位置,需要了解文字的原点坐标位置。

如下图所示,文本框的原点x坐标位于文本框最左侧,y坐标则位于基线上。基线以上为asent,基线以下为decent.

为什么会有基线这个概念,可能会让人产生疑惑,实际上是有原因的。实际上基线相同的文字,即使字体大小不一样,绘制出来的结果是文本底部对齐的。 因为文字底部还有一部分留白,因此文字底部对齐不是基于底部坐标对齐,而是进行基线对齐。

java绘图(基于Graphics2D)第1张

如下图所示,为文字的绘制示例, java提供了api获取文本框的长宽高,asent、decent等,我们需要基于字体Font得到 FontMetrics ,基于FontMetrics 我们就能获取字体高度、asent、decent,结合具体的字符串得到宽度(所以文本绘制实际上不支持换行)。

//指定字体
final Font logoFont = new Font("PingFang SC", Font.BOLD, 50);
FontMetrics metrics = graphics.getFontMetrics(logoFont);

//指定要绘制的字符串
String amount = String.valueOf(coupon.getAmount());

//得到字符串绘制宽度
int logoW = metrics.stringWidth(amount);

//计算绘制原点坐标,
//文本最左边位于x轴logoX int logoX = xStart;

//文本基于
logoH 居中对齐
int logoH = hStart + metrics.getHeight() / 2 - metrics.getDescent(); 

//绘制文本框

graphics.setFont(timeFont);

graphics.setPaint(timeColor);
graphics.drawString(amount, logoX, logoH);

免责声明:文章转载自《java绘图(基于Graphics2D)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇DataSet分页SQL 多条记录分组合成一条数据下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

禁止文本框的记忆性输入

html输入框去除记忆功能 自动完成功能,只需把 autocomplete 设为 off 即可,如:  JS禁止文本框的记忆性输入(已测试:ok) //禁止文本框的记忆性输入 $(document).ready(function(){ //根据id获取input框元素,并设置不自动完成以达到消除文本框的记忆性输入 document.getE...

[ PyQt入门教程 ] PyQt5基本控件使用:单选按钮、复选框、下拉框、文本框

本文主要介绍PyQt5界面最基本使用的单选按钮、复选框、下拉框三种控件的使用方法进行介绍。 1、RadioButton单选按钮/CheckBox复选框。需要知道如何判断单选按钮是否被选中。 2、ComboBox下拉框。需要知道如何对下拉框中的取值进行设置以及代码实现中如何获取用户选中的值。 带着这些问题下面开始介绍这RadioButton单选按钮、Chec...

红头文件格式设置详细教程

一、红头文件的制作及标准 1、进行页面设置 选择“文件”—bai—“页面设设置”选择“页边距”附签,上:3.7厘米 下:3.5厘米 左:2.8厘米 右:2.6厘米。选择“版式”附签,将“页眉和页脚”设置成“奇偶页不同”,在该选项前打“√”。选择“文档网格”附签,“字体设置”,“中文字体”设置为“仿宋”;“字号”设置成“三号”,单击“确定”按钮,选中“指定...

[转]html怎么把这个文本框变为透明

今天写html表单是想把文本框的背景白色去掉后来查了查 如果想要文本框也透明就看看下面的例子吧 样式表: <style type="text/css"><!-- .byte {BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;FONT-SIZE:9pt;BACKGROUND:none transpare...

python-win32操作excel的一些特殊功能

一、代码 特殊操作包括(隐藏列,解锁工作表保护,插入批注,创建文本框,追加修改单元格内容) from openpyxl import load_workbook import win32com.client # 隐藏列 def hidden_column(path, column, sheet_name=0): ''' :param pa...

C#winform的textbox怎么设置滚动条

用 C#开发软件的时候文本框textbox是没有滚动条的,而且是单行文本。下面教大家如何设置多行,并且设置横向滚动条和垂直滚动条。 打开VS工具,创建一个winform窗体项目。系统会自动创建一个主窗体。在左边工具栏搜索textbox后,拉到窗体里面。 这个时候你看到一个单行文本框,右击文本框,点击属性,右边会显示文本框的属性窗口。选择MutilLine...