java绘图(基于Graphics2D)
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)的更多相关文章
- Java中的Graphics2D类基本使用教程
Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...
- java中 awt Graphics2D
Graphics2D ,Graphics 类,提供了对几何形状.坐标转换.颜色管理和文本布局更为复杂的控制.它是用于在 Java(tm) 平台上呈现二维形状.文本和图像的基础类.验证码生成可以用到此类 ...
- Java绘图基础
<零基础学Java> Java绘图基础 绘图是高级程序设计中非常重要的技术,例如,应用程序需要绘制闪屏图像.背景图像.组件外观Web程序可以绘制统计图.数据库存储的图像资源等. Graph ...
- java基础 绘图技术.坦克大战 之java绘图坐标体系(一)
坐标体系介绍 下图说明了java坐标体系.坐标原点位于左上角,以像素为单位,像素是计算机屏幕上最小的显示单位.在java的坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素:第二个 ...
- java 绘图
java 绘图 圆形.线条.矩形.填充 插入图片 文字 //绘图 import java.awt.*; import javax.swing.*; public class Index extends ...
- java中基于TaskEngine类封装实现定时任务
主要包括如下几个类: 文章标题:java中基于TaskEngine类封装实现定时任务 文章地址: http://blog.csdn.net/5iasp/article/details/10950529 ...
- java PriorityBlockingQueue 基于优先级队列,的读出操作可以阻止.
java PriorityBlockingQueue 基于优先级队列.的读出操作可以阻止. package org.rui.thread.newc; import java.util.ArrayLis ...
- Java Swing Graphics Graphics2D的一般用法
Java Swing Graphics Graphics2D的一般用法: 贝塞尔曲线参考:http://www.zhangxinxu.com/wordpress/2014/06/deep-unders ...
- java绘图原理------在窗口界面(或面板上)画出一张或多张图片问题解决方法
/** *@author blovedr * 功能: java绘图原理------在窗口界面(或面板上)画出一张或多张图片问题解决方法 * 日期: 2018年4月28日 16:20 * 注释: ...
随机推荐
- GO获取随机数
使用的"math/rand"包. 基本随机数 a := rand.Int() b := rand.Intn(100) //生成0-99之间的随机数 fmt.Println(a) f ...
- 数据结构Java版之红黑树(八)
红黑树是一种自动平衡的二叉查找树,因为存在红黑规则,所以有效的防止了二叉树退化成了链表,且查找和删除的速度都很快,时间复杂度为log(n). 什么是红黑规则? 1.根节点必须是黑色的. 2.节点颜色要 ...
- 数据结构Java版之遍历二叉树(六)
二叉树是我们在程序中用的最多的一种树(个人观点).最简单的一个二叉树是由一个根节点,两个子节点(一左一右成左右孩子节点)组成.二叉树是数组和链表的结合,即包含了数组的快速查找优点,又包含了链表的快速添 ...
- zabbix—自动发现端口并监控
自动批量检查agent开放的端口 PS:如果服务器上的应用都是固定的,不会随机产生的都可以使用自动发现端口来监控: 如果服务器会随机出现端口且每次启动程序都会改变,可以采用第二种方法,来监控指定的端 ...
- Python自动化测试常用库
基本库: sys 程序和Python解析器的交互 os 启动新进程:操作文件和目录 re 正则表达式,字符串匹配 string 基本字符串操作 inspect 提供自省和反射功能 importlib ...
- Git是怎么Ignore文件的?
Git is one of the most popular version control systems (VCS) available, especially thanks to hosting ...
- Python-matplotlib画图(莫烦笔记)
https://www.zhihu.com/collection/260736383 https://blog.csdn.net/gaotihong/article/details/80983937 ...
- SC3聚类 | 拉普拉斯矩阵 | Laplacian matrix | 图论 | R代码
Laplacian和PCA貌似是同一种性质的方法,坐标系变换.只是拉普拉斯属于图论的范畴,术语更加专业了. 要看就把一篇文章看完整,再看其中有什么值得借鉴的,总结归纳理解后的东西才是属于你的. 问题: ...
- 在dubbo工程中,使用druid监控
介绍:在dubbo项目中,使用druid的监控功能 问题:因为,在网上找勒,很多的资料,显示的都是需要在web.xml中配置 <servlet> <servlet-name>D ...
- Windows下压缩包安装Mysql
1. 下载mysql压缩包 2. 解压到指定目录,例如D:\Program Files\mysql-5.7.25-winx64 3. 在目录下创建配置文件my.ini [mysqld] port = ...