Java Graphics2D的使用
Java Graphics2D的使用
文章目录
- Java Graphics2D的使用
- 前言
- 一、Graphics2D基础方法使用
- 二、绘制不规则多边形
- 三、填充(图片)不规则多边形
- 四、翻转图像(上下、左右180°)
- 五、绘制文字,简单封装(其实就是drawString)
- 六、【扩展】读取配置文件方法
前言
最近实习任务要转换一个绘图相关的.net程序,大概是这样
一开始挺怕的毕竟没弄过图形相关的,之前学习Java的时候碰到也说无脑跳过,大概一周多一点时间我大概解决了这个任务,虽然这个程序难点主要是坐标/比例尺转化未平面绘图坐标,但我觉得学到的Graphics2D相关经验也说非常宝贵的,记录下相关方法,下图是我完成后的
一、Graphics2D基础方法使用
创建对象
//创建图片对象BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);//基于图片对象打开绘图Graphics2D graphics = image.createGraphics();
常用的前置设置(不设置线段/文字不是横竖(就是斜的)的时候会有锯齿)
//消除文字锯齿g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);//消除画图锯齿g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
创建矩形(未绘制)
//声明并创建矩形对象,矩形的左上角是(20,30),宽是300,高是40 Rectangle2D back = new Rectangle2D.Double(20,30,300,40);graphics.fill(back);
创建制圆(未绘制)
//声明并创建圆对象,矩形的左上角是(20,30),宽是100,高是100 Ellipse2D.Double ellipse = new Ellipse2D.Double(20, 20, 100, 100);graphics.draw(ellipse);
创建线段(未绘制)
// 参数就是两个点的xy坐标 x1,y1,x2,y2 Line2D.Float line = new Line2D.Float(10, 10, 20, 20);
绘制 - 基本常用的就是draw(绘制边线) fill(填充:填充内容根据前置设置而定)
// 前置可以进行线条粗细、字体大小、画笔颜色等属性的设置// 设置画笔颜色graphics.setColor(Color.WHITE);// 设置画笔粗细Stroke stroke=new BasicStroke(2.0f);//设置线宽为2.0graphics.setStroke(stroke);// 设置字体大小graphics.setFont(new Font("仿宋",Font.BOLD,fontSize));// 绘制文字 content-内容 xy坐标// 文字画入画布中 graphics.drawString(content, x,y); // 直接放入图形对象 graphics.draw(图形对象); // 可以写入本地文件(文件名无路径默认/src下)//保存图片 JPG表示保存格式ImageIO.write(image,"JPEG",new FileOutputStream("a.jpg"));ImageIO.write(image, "png", new File("abcd.png"));
二、绘制不规则多边形
不多说直接上代码
/*** 绘制多边形* @param pointList 多边形的坐标集* @return* @throws FileNotFoundException* @throws IOException*/public BufferedImage drawPolygon(List<Point> pointList) throws FileNotFoundException, IOException {//得到图片缓冲区BufferedImage image = new BufferedImage//INT精确度达到一定,RGB三原色,宽度512,高度512(1000,600,BufferedImage.TYPE_INT_RGB);//得到它的绘制环境(这张图片的笔)Graphics2D g2 = (Graphics2D) image.getGraphics();//消除文字锯齿g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);//消除画图锯齿g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);//设置画笔白色g2.setColor(Color.white);//全图填充白色底图g2.fillRect(0, 0, image.getWidth(), image.getHeight());//shape的子类,表示一个形状GeneralPath gp=new GeneralPath();// 确定两个点JsonJZD p1=pointList.remove(0);JsonJZD p2=pointList.remove(0);//两个点画第一条直线gp.append(newLine2D.Double(p1.getX(),p1.getY(),p2.getX(),p2.getY()),true);//直线分别与余下的点相连for(Point point: pointList){gp.lineTo(point.getX(),point.getY());}//闭合图形gp.closePath();//设置画笔黑色g2.setColor(Color.BLACK);// 填充网格- 填充内容来自图片image = fillPolygon(image,gp);//填充图形g2.draw(gp);// 翻转图形 - 上下翻转180°
// image = imageMisro(image,UPSIDE_DOWN);// 释放g2资源g2.dispose();// ImageIO.write(image,"JPEG",new FileOutputStream("a.jpg"));//保存图片 JPEG表示保存格式
// ImageIO.write(image, "png", new File("abcd.png"));return image;}
三、填充(图片)不规则多边形
可以看到我的需求有需要使用网格填充图形,这种填充图像的,网上找的都是C或者C#的代码,而且使用的是多边形扫描线填充算法简单剖析(Scan-Line Filling),本来也是想写个这个方法,奈何数学忘得差不多+还是想偷懒,就想继续寻找, 终于,找到了使用TexturePaint类填充图像的写法,处于便于修改填充图像的目的,我就通过properties获取图片路径,具体流程是这样
读取配置文件,获得图片路径
根据图片路径获取图片的BufferedImage对象
使用获取的图片对象创建TexturePaint填充笔
使用获取的填充笔对象设置到graphics2D对象里
使用graphics2D对象的fill方法填充目标不规则多边形
具体代码如下(其中第二个方法是读取配置文件的方法)
BufferedImage对象可以像二一样直接创建,这里选择传参
/*** 填充不规则多边形 - 固定填充 src/main/resources/img/fillImg2.jpg* @param image BufferedImage对象* @param gp 多边形* @return* @throws IOException*/private BufferedImage fillPolygon(BufferedImage image, GeneralPath gp) throws IOException {// 0.读取配置文件String url = getProperties("src/main/resources/fill-Img.properties","fill-img.url");System.out.println("url:" + url);// 1.得到它的绘制环境(这张图片的笔)Graphics2D g2 = (Graphics2D) image.getGraphics();// 2.填充网格- 填充内容来自图片BufferedImage fillImg = ImageIO.read(new File(url)); //要填充图片// 创建矩形(用来放图片的框)Rectangle2D examp = new Rectangle2D.Double(100,100,50,50);// 把图片填充进矩形(矩形大小就是上面矩形的大小) -》 制作成画笔TexturePaint tp = new TexturePaint(fillImg,examp); //Rectangle2D是img大小g2.setPaint(tp);//设置g2的画笔为图片样式的g2.fill(gp);//gp不规则图形return image;}/*** 根据key读取value** @Title: getProperties* @Description: 使用缓冲输入流读取配置文件,然后将其加载,再按需操作* 绝对路径或相对路径, 如果是相对路径,则从当前项目下的目录开始计算,* 如:当前项目路径/config/config.properties,* 相对路径就是config/config.properties** @param filePath* @param keyWord* @return* @return String* @throws*/public static String getProperties(String filePath, String keyWord){Properties prop = new Properties();String value = null;try {// 通过输入缓冲流进行读取配置文件InputStream InputStream = new BufferedInputStream(new FileInputStream(new File(filePath)));// 加载输入流prop.load(InputStream);// 根据关键字获取value值value = prop.getProperty(keyWord);} catch (Exception e) {e.printStackTrace();}return value;}
四、翻转图像(上下、左右180°)
/*** 镜像处理 180°水平和垂直翻转* type = 0 表示上下翻转,type = 1 表示左右翻转* @param bufferedimage 需要翻转的BufferedImage对象* @param type* @return*/public static BufferedImage imageMisro(BufferedImage bufferedimage,int type ) {try{int w = bufferedimage.getWidth();int h = bufferedimage.getHeight();int[][] datas = new int[w][h];for (int i = 0; i < h; i++) {for (int j = 0; j < w; j++) {// getRGB 获取图像中的像素整数值 二进制格式datas[j][i] = bufferedimage.getRGB(j, i);}}int[][] tmps = new int[w][h];if (type == 0) {for (int i = 0, a = h - 1; i < h; i++, a--) {for (int j = 0; j < w; j++) {tmps[j][a] = datas[j][i];}}} else if (type == 1) {for (int i = 0; i < h; i++) {for (int j = 0, b = w - 1; j < w; j++, b--) {tmps[b][i] = datas[j][i];}}}for (int i = 0; i < h; i++){for (int j = 0; j<w ;j++){bufferedimage.setRGB(j, i, tmps[j][i]);}}return bufferedimage;//ImageIO.write(bufferedimage, "jpg", file);} catch (Exception e) {e.printStackTrace();}return null;}
五、绘制文字,简单封装(其实就是drawString)
/*** content 需要绘制的文字* interval 文字两端空余像素* fontSize 文字大小* x 绘制起始点x* y 绘制起始点y* g2 graphics2D对象*/public void drawWord(String content,int fontSize, float x, float y,Graphics2D g2) {//消除文字锯齿g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);//消除画图锯齿g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2.setPaint(Color.BLACK);g2.setFont(new Font("仿宋",Font.BOLD,fontSize));g2.drawString(content, x,y); // 文字画入画布中}
六、【扩展】读取配置文件方法
这里推荐一个博主记录的比较全面[Java 读取 .properties 配置文件的几种方式](https://www.cnblogs.com/sebastian-tyd/p/7895182.html)
Java Graphics2D的使用相关推荐
- java Graphics2D类
Java 2D拥有强大的二维图形处理能力,这些功能主要是由Graphics2D类来完成的,该类是Graphics类的一个子类.它的特点是把所绘的图形当成一个对象来处理,绘制前先创建对象. 绘制2D直线 ...
- Java Graphics2D类的绘图方法
Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...
- java graphics2d 画圆_java Graphics2D 画图
平时出图都是前端画图的,本次画图是对响应时间有要求,所有给后端提的需求.这里就给出一个demo 还有列出其中遇到的几个小问题 1 首先列出结果图 2 遇到的问题 1 这是两张图片覆盖的. cov ...
- java graphics2d 乱码_Graphics2D 中文乱码
今天遇到了一个乱码问题,合成的小票图片上的中文全部变成了口口口,后来在网上查了资料,发现是Graphics2D用了宋体字,而linux服务器上没有对应的字体库. 把本地的字体库上传上去就解决了. 本地 ...
- java graphics dispose_java图形处理-Java Graphics2D
java.awt 类 Graphics2D java.lang.Object 继承者 java.awt.Graphics 继承者 java.awt.Graphics2D public abstract ...
- java graphics2d旋转_反转Java Graphics2D缩放和旋转坐标
如果您保留了在绘制图像时使用的AffineTransform的副本,则可以使用 AffineTransform.inverseTransform(Point2D ptSrc, Point2D ptDs ...
- java graphics2d renderinghints_java - Graphics2D错误 - 堆栈内存溢出
我正在尝试创建ASCII艺术作品,并且此错误不断出现. 我不知道怎么了. 线程"主"中的异常java.lang.IllegalArgumentException:抗锯齿文本模式与v ...
- java graphics2d旋转_反向Java Graphics2D缩放和旋转坐标
小编典典 编辑 :如果捕获当前Graphics2D绘画的变换,请当心将Graphics2D其重新用于同一窗口/面板的多个轻量级子项,因为这样变换将相对于父组件,而鼠标坐标将相对于父组件这个孩子.您需要 ...
- java graphics2d 矩形_使用java.awt.Graphics2D画矩形
下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. import java.awt.Graphics; import java.awt.Gra ...
- java graphics2d 绘图_Java编程 Graphics2D类的绘图方法
现在都讲究立体的效果,Graphics2D类的绘图方式就属于高级绘图了,在我们日常生活中经常提到的2d.3d电影都是立体的,而编程语言也是一样,可以实现2d的效果哦,下面就让我们一起来学习下吧! Ja ...
最新文章
- mybatis实现增删改查xml配置和后端Java编程完整教程
- OSG使用更新回调来更改模型
- 微信突然出现redirect_uri 参数错误
- 调整Tomcat上的参数提高性能[转]
- python编写sql注入工具-利用Python实现SQL注入 - Python黑客编程入门系列 - 8
- MS SQL 数据库状态为SUSPECT的处理方法
- 软件基本功:不要给代码加系数
- Canny算子边缘检测——非极大值抑制Non-Maximum Suppression
- VS不能使用回车键和删除键及其他键问题
- 抖音热门技术998 修改视频md5
- 腾讯云数据库CDB介绍及数据库与应用数据库分析
- Java工具类之String类
- Delphi Math单元函数
- linux网卡加vlan标签,如何在 CentOS/RHEL 系统中使用带 VLAN 标记的以太网卡
- 云信api_网易数帆开源贡献获业界肯定,轻舟API网关获OSCAR尖峰开源技术创新奖...
- AASM rule of scoring sleep stages using EEG signal
- 好消息!!!XMind出视频教程了
- 解析移动互联网四大App云加固平台市场和质量对比
- C语言编写程序:判断某年份是否为闰年
- mysql连接异常:The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zo
热门文章
- 纺织服装外贸行业解决方案丨汇信外贸软件
- 数据库作业8:SQL练习5 - SELECT(嵌套查询EXISTS、集合查询、基于派生表的查询)
- pytorch 预训练模型
- 矩阵标准型的系数是特征值吗_矩阵分解术,不得不从高斯说起
- postgresql中实现按周统计详解
- 水滴的“创益矩阵”:“万物”皆可连接公益
- Centos7重置用户密码
- C++11线程中的几种锁
- 单相全控桥有源逆变电路matlab仿真,单相桥式全控整流与有源逆变电路的MATLAB仿真设计...
- bzoj2037 创世纪