创建了一个JAVA画图功能图形库
2013-03-07 15:33
435 查看
通过JAVA可以很容易绘制出各种各样的图形,如矩形,方型,椭圆以及正圆等,直线和文本当然更不再话下。主要是通过BufferedImage和Graphics2D实现。做了一个demo演示,效果如下:
下面来描述实现过程。
库文件主要包括两个类文本:FontProperty和PrintGraphics。其中FontProperty用于定义字体的各个属性,如粗体、斜体、下划线等等;PrintGraphics主要定义各种图形的绘制功能。
先看FontProperty.java:
该文件很简单,就只有一个设置字体属性的方法。
接着看PrintGraphics.java文件:
程序里面都有详细的注释信息,所以不难看懂的。
最后写一个测试demo.java程序:
Demo文件的注释也很详细的,都是调用前面两个库文件定义的功能函数,最后会将图像通过窗口显示出来,同时会保存到/tmp/demo.jpg。显示效果见文档开始。
可以将三个java文件放到同一目录下,然后编译并运行:
注意,根据你的实际情况,demo.java中的两处路径可能需要修改一下。
说明:该方案仅适用于PC环境,如果是Android系统,需要其它方法实现,后面会讨论Android下如何实现。
下面来描述实现过程。
库文件主要包括两个类文本:FontProperty和PrintGraphics。其中FontProperty用于定义字体的各个属性,如粗体、斜体、下划线等等;PrintGraphics主要定义各种图形的绘制功能。
先看FontProperty.java:
public class FontProperty{ boolean bBold; //是否粗体 boolean bItalic; //是否斜体 boolean bUnderLine; //是否下划线 boolean bStrikeout; //是否删除线 int iSize; //字体大小 String sFace; //字体类型,默认留空("")即可,表示使用系统默认字体,当然也可以指定如"宋体" //设置字体参数 public void setF(boolean bBold, boolean bItalic, boolean bUnderLine, boolean bStrikeout, int iSize, String sFace){ this.bBold = bBold; this.bItalic = bItalic; this.bUnderLine = bUnderLine; this.bStrikeout = bStrikeout; this.iSize = iSize; this.sFace = sFace; } }
该文件很简单,就只有一个设置字体属性的方法。
接着看PrintGraphics.java文件:
import java.awt.*; import java.awt.geom.*; import javax.swing.*; import java.io.File; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.util.Hashtable; import java.awt.font.TextAttribute; import javax.swing.JFrame; public class PrintGraphics{ public BufferedImage bi = null; public Graphics2D g2 = null; public double length = 0.0; public int width; /** * 获取图像的实际长度 * 因为画布定义的长度是其宽度的10倍,所以最后会根据使用的实际长度进行截取 */ public int getLength(){ return (int)this.length+20; } /** * 初始化画布BufferedImage和画笔Graphics2D,其中宽度为参数,长度为宽度的10倍 * 画布背景为白色,画笔为黑色 */ public void initBuff(int width){ int height = 10*width; this.bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); this.g2 = (Graphics2D)this.bi.getGraphics(); this.g2.setBackground(Color.WHITE); this.g2.clearRect(0, 0, width, height); this.g2.setPaint(Color.BLACK); this.width = width; } // 根据初始的字体属性值对字体进行设置 public Font setFontProperty(FontProperty fp){ int fontStyle = 0; int fontFlag = 0; if(fp.sFace != ""){ String fontNames[]; //获取系统所有字体列表,然后判断用户指定的字体是否存在 fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); for(int i=0;i<fontNames.length;i++){ if(fontNames[i].equals(fp.sFace)){ fontFlag = 1; break; } } //如果不存在则留空,表示使用系统默认字体 if(fontFlag == 0){ System.out.println("Your font face \"" + fp.sFace + "\" is not exist, default is used."); fp.sFace = ""; } } Font font = null; //设置粗体 if(fp.bBold){ fontStyle = 1; font = new Font(fp.sFace, Font.BOLD, fp.iSize); } //设置斜体 if(fp.bItalic){ if(fontStyle == 0){ fontStyle = 1; font = new Font(fp.sFace, Font.ITALIC, fp.iSize); } else{ font = new Font(fp.sFace, Font.BOLD|Font.ITALIC, fp.iSize); } } //设置常规体 if(fontStyle == 0){ font = new Font(fp.sFace, Font.PLAIN, fp.iSize); } //设置下划线和删除线 if(fp.bUnderLine || fp.bStrikeout){ Hashtable<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>(); if(fp.bUnderLine){ map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); } if(fp.bStrikeout){ map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON); } font = font.deriveFont(map); } return font; } //设置线宽 public Stroke setLineWidth(double width){ String f = "" + width + "f"; Stroke stk = new BasicStroke(Float.parseFloat(f)); return stk; } //使用指定的字体绘制文本,其中(x,y)是指文本起始位置的左下点坐标,所以y不可为0 public void drawText(double x, double y, String nStr, FontProperty fp){ Font font = this.setFontProperty(fp); this.g2.setFont(font); this.g2.drawString(nStr, (int)x, (int)y); if(this.length < y){ this.length = y; } } //使用指定的宽度绘制直线,其中(x1,y1)为起始点坐标,(x2,y2)为终点坐标 public void drawLine(double x1, double y1, double x2, double y2, double w){ Stroke stk = this.setLineWidth(w); this.g2.setStroke(stk); this.g2.draw(new Line2D.Double(x1, y1, x2, y2)); //获取画布实际使用长度,下同 double max = 0; max = y1>y2?y1:y2; if(this.length < max){ this.length = max; } } //使用指定的宽度绘制矩形或方型,其中(x1,y1)为左上角坐标,width和height分别指定矩形或方型的宽度及高度 public void drawRectangle(double x, double y, double width, double height, double w){ Stroke stk = this.setLineWidth(w); this.g2.setStroke(stk); this.g2.draw(new Rectangle2D.Double(x, y, width, height)); if(this.length < y+height){ this.length = y+height; } } //使用指定的宽度绘制椭圆或正圆,其中(x1,y1)为圆的外切矩形或方型的左上角坐标,(x2,y2)为圆的外切矩形或方型的右下角坐标 public void drawEllips(double x1, double y1, double x2, double y2, double w){ Stroke stk = this.setLineWidth(w); this.g2.setStroke(stk); Rectangle2D rect=new Rectangle2D.Double(); rect.setFrameFromDiagonal(x1, y1, x2, y2); Ellipse2D ellipse=new Ellipse2D.Double(); ellipse.setFrame(rect); this.g2.draw(ellipse); double max = 0; max = y1>y2?y1:y2; if(this.length < max){ this.length = max; } } //插入指定路径的图片,其中(x,y)是指图片起始位置的左上点坐标 public void drawImage(double x, double y, String pathname){ try{ BufferedImage image=ImageIO.read(new File(pathname)); this.g2.drawImage(image, (int)x, (int)y, null); if(this.length < y+image.getHeight()){ this.length = y+image.getHeight(); } }catch(java.io.IOException ioe){ioe.printStackTrace();} } //将图像通过frame窗口显示出来 public void printShow(){ JFrame jframe = new JFrame(); jframe.setTitle("Preview Image"); //设置frame是,长度和宽度都适当的增加了一点,这样最终的图片周边会留点白边,比较好看 jframe.setSize(this.width+20, this.getLength()+40); //为frame窗口添加关闭属性 jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //根据实际图像长度截取图像,(0,0)表示图像左上点坐标,后两个参数表示右下角坐标 BufferedImage img = this.bi.getSubimage(0,0,this.width,this.getLength()); ImageIcon ii = new ImageIcon(img); JLabel lb = new JLabel(ii); jframe.add(lb); //显示frame窗口 jframe.setVisible(true); //销毁g2对象 this.g2.dispose(); } }
程序里面都有详细的注释信息,所以不难看懂的。
最后写一个测试demo.java程序:
import java.io.File; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; class Demo{ public static void main(String[] args){ //获取画图实例 PrintGraphics pg = new PrintGraphics(); //初始化画布,宽度为576px,则长度为5760px pg.initBuff(576); //插入一张图片,根据自己的图片位置进行更改即可 pg.drawImage(30, 0, "/home/zwang/tmp/logo.gif"); //获取字体实例 FontProperty fp = new FontProperty(); //初始化字体,黑体,24号 fp.setF(true, false, false, false, 24, ""); //绘制文本 pg.drawText(215, 45, "北京威控睿博科技有限公司", fp); //绘制直线 pg.drawLine(0, 70, 576, 70, 5.0); //绘制各种格式的文本 fp.setF(false, false, false, false, 18, ""); pg.drawText(150, 95, "这是一行普通文体", fp); fp.setF(true, false, false, false, 18, ""); pg.drawText(150, 120, "这是一行粗体文体", fp); fp.setF(false, true, false, false, 18, ""); pg.drawText(150, 145, "这是一行斜体文体", fp); fp.setF(false, false, true, false, 18, ""); pg.drawText(150, 170, "这是一行下划线文体", fp); fp.setF(false, false, false, true, 18, ""); pg.drawText(150, 195, "这是一行删除线文体", fp); fp.setF(true, true, true, true, 18, ""); pg.drawText(150, 220, "这是一行混合格式文体", fp); pg.drawLine(0, 230, 576, 230, 2.0); //绘制矩形及说明文本 fp.setF(false, false, false, false, 15, ""); pg.drawRectangle(10, 250, 360, 180, 2.0); pg.drawText(135, 340, "线宽2.0的矩形", fp); //绘制方形及说明文本 pg.drawRectangle(380, 250, 180, 180, 4.0); pg.drawText(420, 340, "线宽4.0的方形", fp); //绘制椭圆及说明文本 pg.drawEllips(10, 450, 370, 630, 3.0); pg.drawText(135, 540, "线宽3.0的椭圆", fp); //绘制正圆及说明文本 pg.drawEllips(380, 450, 560, 630, 6.0); pg.drawText(420, 540, "线宽6.0的正圆", fp); pg.drawLine(0, 650, 576, 650, 4.0); //显示图像窗口 pg.printShow(); //将图像保存到指定位置的jpg格式文件,当然也可以为png及其它格式 BufferedImage img=pg.bi.getSubimage(0,0,576,pg.getLength()); //pg.g2.dispose(); //free g2 //可根据实际系统更改这个路径 File file = new File("/tmp/demo.jpg"); try{ ImageIO.write(img, "jpg", file); }catch(java.io.IOException ioe){ioe.printStackTrace();} } }
Demo文件的注释也很详细的,都是调用前面两个库文件定义的功能函数,最后会将图像通过窗口显示出来,同时会保存到/tmp/demo.jpg。显示效果见文档开始。
可以将三个java文件放到同一目录下,然后编译并运行:
$ javac demo.java $ java Demo
注意,根据你的实际情况,demo.java中的两处路径可能需要修改一下。
说明:该方案仅适用于PC环境,如果是Android系统,需要其它方法实现,后面会讨论Android下如何实现。
相关文章推荐
- 【Java】使用JFrame监听事件创建一个复制文本功能的窗体程序与按钮快捷键
- java Runtime 中 的一些功能(创建一个进程 打开某个软件和关闭)
- 猜数字游戏。编写一个Java应用程序,实现功能:
- 开源一个Java Class实现Openfire登陆、推出、消息发送,方便其他系统集成IM功能了
- java 创建邮件发送功能
- java多线程之:创建开启一个线程的开销
- java中如何创建一个指定文件,一个指定的目录
- 为你的Java应用嵌入一个功能强大的文字编辑器
- Java【多线程知识总结(6)】使用Runnable接口创建多线程,处理同一个资源
- 如何用Maven创建一个普通Java项目
- BuguMongo是一个MongoDB Java开发框架,集成了DAO、Query、Lucene、GridFS等功能
- Java 小程序:实现一个购物流程的功能
- Java GUI之创建一个长宽尺寸为屏幕尺寸一半的框架,并显示在屏幕的正中心
- Spring Boot . 2 -- 用Spring Boot 创建一个Java Web 应用
- java 在已有的学生中插入一个学生(需要用类去创建另一个类的属性)
- java 创建一个进程
- java多线程中校验一个后台线程中创建一个新线程,新线程是否是后台线程
- java 创建一个File文件对象
- JAVA--第十周实验--封装一类对象,功能是随机产生一个2000年后的年份,并输出该年2月的日历页(草稿)
- JAVA 画图板实现(基本画图功能+界面UI)一、界面实现