1.绘图基本操作

请参考下面基础示例:

         int width = 200, height = 250;
//创建图片对象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
//基于图片对象打开绘图
Graphics2D graphics = image.createGraphics();
//绘图逻辑 START (基于业务逻辑进行绘图处理)…… //绘制圆形
graphics.setColor(Color.BLACK);
Ellipse2D.Double ellipse = new Ellipse2D.Double(20, 20, 100, 100);
graphics.draw(ellipse); // 绘图逻辑 END
//处理绘图
graphics.dispose();
//将绘制好的图片写入到图片
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.进行绘制

         //将图片转换为BufferedImage对象
BufferedImage bufferedImage = ImageIO.read(new File("C:\\Users\\minggliu\\Pictures\\test\\test.png"));
//计算绘制位置
int x = 0, y = 0;
//执行绘制
//graphics.drawImage(bufferedImage.getScaledInstance(imageW, imageH, Image.SCALE_DEFAULT),100, 100, null);
//graphics.drawImage(bufferedImage, 0, 0, width / 2, height / 2, null);
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提供了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)的更多相关文章

  1. Java中的Graphics2D类基本使用教程

    Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...

  2. java中 awt Graphics2D

    Graphics2D ,Graphics 类,提供了对几何形状.坐标转换.颜色管理和文本布局更为复杂的控制.它是用于在 Java(tm) 平台上呈现二维形状.文本和图像的基础类.验证码生成可以用到此类 ...

  3. Java绘图基础

    <零基础学Java> Java绘图基础 绘图是高级程序设计中非常重要的技术,例如,应用程序需要绘制闪屏图像.背景图像.组件外观Web程序可以绘制统计图.数据库存储的图像资源等. Graph ...

  4. java基础 绘图技术.坦克大战 之java绘图坐标体系(一)

    坐标体系介绍 下图说明了java坐标体系.坐标原点位于左上角,以像素为单位,像素是计算机屏幕上最小的显示单位.在java的坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素:第二个 ...

  5. java 绘图

    java 绘图 圆形.线条.矩形.填充 插入图片 文字 //绘图 import java.awt.*; import javax.swing.*; public class Index extends ...

  6. java中基于TaskEngine类封装实现定时任务

    主要包括如下几个类: 文章标题:java中基于TaskEngine类封装实现定时任务 文章地址: http://blog.csdn.net/5iasp/article/details/10950529 ...

  7. java PriorityBlockingQueue 基于优先级队列,的读出操作可以阻止.

    java PriorityBlockingQueue 基于优先级队列.的读出操作可以阻止. package org.rui.thread.newc; import java.util.ArrayLis ...

  8. Java Swing Graphics Graphics2D的一般用法

    Java Swing Graphics Graphics2D的一般用法: 贝塞尔曲线参考:http://www.zhangxinxu.com/wordpress/2014/06/deep-unders ...

  9. java绘图原理------在窗口界面(或面板上)画出一张或多张图片问题解决方法

    /** *@author blovedr * 功能: java绘图原理------在窗口界面(或面板上)画出一张或多张图片问题解决方法 * 日期: 2018年4月28日     16:20 * 注释: ...

随机推荐

  1. GoCN每日新闻(2019-09-24)

    1. Go 搭建的高效网页爬虫:https://creekorful.me/building-fast-modern-web-crawler/ 2. Go 时区处理:https://medium.co ...

  2. golang-flag - 命令行参数解析

    flag - 命令行参数解析 在写命令行程序(工具.server)时,对命令参数进行解析是常见的需求.各种语言一般都会提供解析命令行参数的方法或库,以方便程序员使用.如果命令行参数纯粹自己写代码解析, ...

  3. php单点登录SSO(Single Sign On)的解决思路

    一.什么是单点登录 解释:登录一个系统后,其它系统无需再次登录,即可进入. 二.举个例子: 你登录了淘宝,然后你进入天猫,发现你不用登录了.这时你要注意到,淘宝跟天猫可是完全不一样的域名. 你登录淘宝 ...

  4. Dns的作用

    DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串 DNS系统:通过 ...

  5. [WC2010]重建计划(长链剖分版)

    传送门 Description Solution 时隔多年,补上了这题的长链剖分写法 感觉比点分治要好写的多 我们假设\(pos\)是当前点的\(dfn\),它距离所在链的底端的边的数量是\(len\ ...

  6. 01_tf和numpy的区别

    import numpy as npimport tensorflow as tf # 这里是为了演示numpy和tf的区别.np.random.seed(43) x_data = np.random ...

  7. TLS整理(下):TLS如何保证安全

    明文 无法验证服务器的真实性 从而引出了TLS.本篇就来着重介绍下TLS. 说起TLS可能有些人还比较陌生,但如果说到SSL,那知道的人就更多了.TLS其实就是SSL发展而来,版本演进大体为SSL 2 ...

  8. RK3399 pro 开发记录

    RK3399有三种启动模式:1.Normal模式:2.Loader模式:3.MaskRom模式.      Normal模式是正常的启动过程,各个组件依次加载,直到正常进入系统.      Loade ...

  9. win10创建Ubuntu16.04子系统,安装常用软件以及图形界面(包括win10远程桌面连接Ubuntu)

    一.开启win10子系统 [ Windows Subsystem for Linux(WSL)] 二.基本配置 三.安装常用的软件 安装配置zsh 使用 bash 客户端软件 cmder(其实是win ...

  10. PathVariable传过来的中文乱码是怎么回事

    今天在写一个spring mvc程序,由于客户原来设计的原因,不能传id过来,只能传名称,结果发现收到的数据是乱码. 百度之后,找到别人的解决方案,试了下没问题,转载一下.使用的web服务器是Tomc ...