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获取图片路径,具体流程是这样

  1. 读取配置文件,获得图片路径

  2. 根据图片路径获取图片的BufferedImage对象

  3. 使用获取的图片对象创建TexturePaint填充笔

  4. 使用获取的填充笔对象设置到graphics2D对象里

  5. 使用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的使用相关推荐

  1. java Graphics2D类

    Java 2D拥有强大的二维图形处理能力,这些功能主要是由Graphics2D类来完成的,该类是Graphics类的一个子类.它的特点是把所绘的图形当成一个对象来处理,绘制前先创建对象. 绘制2D直线 ...

  2. Java Graphics2D类的绘图方法

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

  3. java graphics2d 画圆_java Graphics2D 画图

    平时出图都是前端画图的,本次画图是对响应时间有要求,所有给后端提的需求.这里就给出一个demo 还有列出其中遇到的几个小问题 1 首先列出结果图 2   遇到的问题 1  这是两张图片覆盖的. cov ...

  4. java graphics2d 乱码_Graphics2D 中文乱码

    今天遇到了一个乱码问题,合成的小票图片上的中文全部变成了口口口,后来在网上查了资料,发现是Graphics2D用了宋体字,而linux服务器上没有对应的字体库. 把本地的字体库上传上去就解决了. 本地 ...

  5. java graphics dispose_java图形处理-Java Graphics2D

    java.awt 类 Graphics2D java.lang.Object 继承者 java.awt.Graphics 继承者 java.awt.Graphics2D public abstract ...

  6. java graphics2d旋转_反转Java Graphics2D缩放和旋转坐标

    如果您保留了在绘制图像时使用的AffineTransform的副本,则可以使用 AffineTransform.inverseTransform(Point2D ptSrc, Point2D ptDs ...

  7. java graphics2d renderinghints_java - Graphics2D错误 - 堆栈内存溢出

    我正在尝试创建ASCII艺术作品,并且此错误不断出现. 我不知道怎么了. 线程"主"中的异常java.lang.IllegalArgumentException:抗锯齿文本模式与v ...

  8. java graphics2d旋转_反向Java Graphics2D缩放和旋转坐标

    小编典典 编辑 :如果捕获当前Graphics2D绘画的变换,请当心将Graphics2D其重新用于同一窗口/面板的多个轻量级子项,因为这样变换将相对于父组件,而鼠标坐标将相对于父组件这个孩子.您需要 ...

  9. java graphics2d 矩形_使用java.awt.Graphics2D画矩形

    下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. import java.awt.Graphics; import java.awt.Gra ...

  10. java graphics2d 绘图_Java编程 Graphics2D类的绘图方法

    现在都讲究立体的效果,Graphics2D类的绘图方式就属于高级绘图了,在我们日常生活中经常提到的2d.3d电影都是立体的,而编程语言也是一样,可以实现2d的效果哦,下面就让我们一起来学习下吧! Ja ...

最新文章

  1. mybatis实现增删改查xml配置和后端Java编程完整教程
  2. OSG使用更新回调来更改模型
  3. 微信突然出现redirect_uri 参数错误
  4. 调整Tomcat上的参数提高性能[转]
  5. python编写sql注入工具-利用Python实现SQL注入 - Python黑客编程入门系列 - 8
  6. MS SQL 数据库状态为SUSPECT的处理方法
  7. 软件基本功:不要给代码加系数
  8. Canny算子边缘检测——非极大值抑制Non-Maximum Suppression
  9. VS不能使用回车键和删除键及其他键问题
  10. 抖音热门技术998 修改视频md5
  11. 腾讯云数据库CDB介绍及数据库与应用数据库分析
  12. Java工具类之String类
  13. Delphi Math单元函数
  14. linux网卡加vlan标签,如何在 CentOS/RHEL 系统中使用带 VLAN 标记的以太网卡
  15. 云信api_网易数帆开源贡献获业界肯定,轻舟API网关获OSCAR尖峰开源技术创新奖...
  16. AASM rule of scoring sleep stages using EEG signal
  17. 好消息!!!XMind出视频教程了
  18. 解析移动互联网四大App云加固平台市场和质量对比
  19. C语言编写程序:判断某年份是否为闰年
  20. mysql连接异常:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zo

热门文章

  1. 纺织服装外贸行业解决方案丨汇信外贸软件
  2. 数据库作业8:SQL练习5 - SELECT(嵌套查询EXISTS、集合查询、基于派生表的查询)
  3. pytorch 预训练模型
  4. 矩阵标准型的系数是特征值吗_矩阵分解术,不得不从高斯说起
  5. postgresql中实现按周统计详解
  6. 水滴的“创益矩阵”:“万物”皆可连接公益
  7. Centos7重置用户密码
  8. C++11线程中的几种锁
  9. 单相全控桥有源逆变电路matlab仿真,单相桥式全控整流与有源逆变电路的MATLAB仿真设计...
  10. bzoj2037 创世纪