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 * 注释: ...
随机推荐
- mysql bigint与bigint unsigned
-------------------------------以下是个人根据网上翻阅加个人理解总结结果------------------------------- mysql 表中数据类型和存储过程 ...
- Maven 异常 druid jar冲突
异常: 十二月 25, 2017 11:04:41 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin 警告: [SetPropert ...
- CF1203F2 Complete the Projects (hard version)(结论+背包+贪心)
题目 做法 对于加分的直接贪心 而掉分的用排序后的背包动规 假设有两个物品\((a_1,b_1)(a_2,b_2)\) 选第一个物品后无法选择第二个物品,假设开始值为\(r\):\(r>a_1, ...
- Java 基础:抽象类与接口
1.什么是抽象 当父类的某些方法不确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract来修饰该类[抽象类]. 我们都知道,父类是将子类所共同拥有的属性和方法进行抽取,这些属 ...
- mysql 连接服务器报ERROR 1130 ,mysql服务正常运行
今天办公电脑的mysql罢工了,折腾了半天,记录一下. 错误如下: ERROR 1130 (HY000): Host 'localhost' is not allowed to connect to ...
- python中whl的讲解
whl 格式:这是一个压缩包,在其中包含了py文件,以及经过编译的pyd文件. 这个格式可以使文件在不具备编译环境的情况下,选择合适自己的python环境进行安装. 安装方法如下 进入命令行输入:pi ...
- ActiveMq 本地安装及启动(Windows)
首先下载MQ的安装包 http://activemq.apache.org/download.html 1.点击最新版本的ActiveMQ的 2.这里有窗户版本和Linux的的版本,这里我们选择窗口版 ...
- 20190729 将博客搬至CSDN
为更方便技术交流, 现将博客园内容搬迁至csdn, https://blog.csdn.net/lxw1844912514
- Bayesian Statistics for Genetics | 贝叶斯与遗传学
Common sense reduced to computation - Pierre-Simon, marquis de Laplace (1749–1827) Inventor of Bayes ...
- idea断点调试学习随笔
1,rerun XXX,这个就是直接重新跑某个程序.2,这个相当于eclipse里面的f8,直接跑完,到下一个断点停下,没有就直接跑完程序.3,停止项目或者程序.要是自己的main呢,点一下就停下了, ...