JavaAWT绘图
# JavaAWT绘图
# 绘制图形
# Canvas画布类
Class Canvas
java.lang.Object java.awt.Component java.awt.Canvas
用来 绘制图形 或 捕获用户输入的事件。绘制图形需要绘图方法实现绘制图形
方法 | 说明 |
---|---|
paint(Graphics g) | 绘图 |
repaint(Graphics g) | 重新绘图(刷新 |
# Graphics绘图类
Class Graphics
java.lang.Object java.awt.Graphics
Graphics绘图类 是所有图形的抽象基类,它提供了绘图常用的方法
图形 | 方法 |
---|---|
弧形 | drawArc(int x , int y , int width , int height , int startAngle , int arcAngle) |
直线 | drawLine(int x1 , int y1 , int x2 , int y2) |
椭圆 | drawOval(int x , int y , int width , int height) |
多边形 | drawPolygon(int[] xPoints , int[] yPoints , int nPoints) |
多边线 | drawPolyline(int[] xPoints , int[] yPoints , int nPoints) |
矩形 | drawRect(int x , int y , int width , int height) |
圆角矩形 | drawRoundRect(int x , int y , int width , int height , int arcWidth, int arcHeight) |
实心弧形 | fillArc(int x , int y , int width , int height , int height , int startAngle , int arcAngle) |
实心椭圆 | fillOval(int x , int y , int width , int height) |
实心多边形 | fillPolygon(int[] xPoints , int[] yPoints , int nPoints) |
实心矩形 | fillRect(int x , int y , int width , int height) |
实心圆角矩形 | fillRoundRect(int x , int y , int width , int height , int arcWidth, int arcHeight) |
参数 | 说明 |
---|---|
x | 坐标X |
y | 坐标Y |
width | 宽度 |
height | 高度 |
startAngle | 起始角度 |
arcAngle | 相对起始角度的弧的角度范围 |
xPoints | X坐标的数组 |
yPoints | Y坐标的数组 |
nPoints | 总数 |
arcWidth | 四角圆弧的水平直径 |
arcHeight | 四角圆弧的垂直直径 |
# Graphics2D新绘图类
Class Graphics2D
java.lang.Object java.awt.Graphics java.awt.Graphics2D
Graphics类的扩展 Graphics2D新绘图类,它必须要 draw()和fill() 方法 绘图 方法的参数需要Shape图形接口实现绘图(接口在 java.awt.geom 包下
抽象方法 | 说明 |
---|---|
draw(Shape form) | 绘制图形 |
fill(Shape form) | 填充图形 |
form:Shape图形接口的对象
# 代码绘制流程
- 创建窗体对象
- 创建 Canvas画布类 并添加入窗体容器里
- 调用 Canvas画布类中 paint(Graphics g)方法
- 调用 paint(Graphics g)方法 中的 Graphics对象 或 创建Graphics2D绘图对象
- 调用 绘图的抽象方法 实现绘图
方式二:(从步骤4开始,适合批量绘图)
- 实例 java.awt.geom包 中的图形类,赋值至 Shape接口 对象
- 传参 调用 Graphics2D类 中的 draw() 或 fill() 方法 实现绘图
大致例子:
大致例子:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
public class DrawFrame extends JFrame {
private Container c = getContentPane();
public DrawFrame(){
setBounds(400 , 300 , 360 , 160);
setDefaultCloseOperation(3);
//Canvas匿名画布类 重写paint()绘图方法
c.add(new Canvas(){
@Override
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
//方法一
g2.drawRoundRect(10 , 5 , 100 , 100 , 10 , 10);
g2.fillOval(20 , 15 , 80 , 80);
//方法二
//声明图形数组
Shape[] shapes = new Shape[4];
//以double精度创建
//绘制圆
shapes[0] = new Ellipse2D.Double(120, 5 , 100 ,100);
//绘制矩形
shapes[1] = new Rectangle2D.Double(230 ,5 ,100 ,100);
//绘制矩形
shapes[2] = new Rectangle2D.Double(130 ,15 ,80 ,80);
//绘制圆
shapes[3] = new Ellipse2D.Double(240 ,15 ,80 ,80);
for(Shape tmp : shapes){
//Rectangle2D bounds = tmp.getBounds2D(); (Rectangle2D是RectangularShape的子类
//RectangularShape类 用来查询和修改矩形框架的类
RectangularShape bounds = tmp.getBounds2D();
if(bounds.getWidth() == 80){
//第二组图形创建
g2.fill(tmp);
}else{
//第一组图形创建
g2.draw(tmp);
}
}
}
});
}
public static void main(String[] args) {
new DrawFrame().setVisible(true);
}
}
运行结果:
# 绘图属性
# 颜色
Class Color
java.lang.Object java.awt.Color
Color类 提供设置颜色的对象 构造方法
Color(int R , int G , int B) Color(int RGB)
参数说明
R: 红色颜色值 G: 绿色颜色值 B: 蓝色颜色值 RGB: 组合RGB颜色值
Color常量值 有已定义好的颜色对象,可直接调用(自行API查
# 画笔
Class BasicStroke
java.lang.Object java.awt.BasicStroke
BasicStroke类 为图形轮廓定义基本渲染属性(定义边线属性 实现前提需要Stroke接口实现类!!!
**构造方法 **
BasicStroke() BasicStroke(float width) BasicStroke(float width , int cap , int join) BasicStroke(float width , int cap , int join , float miterlimit) BasicStroke(float width , int cap , int join , float miterlimit , float[] dash , float dash_phase)
参数 | 说明 |
---|---|
width | 画笔宽度 |
cap | 线端点的装饰 |
join | 应用在路径线段交会处的装饰 |
miterlimit | 斜接处的剪裁限制 |
dash | 虚线模式的数组 |
dash_phase | 开始虚线模式的偏移量 |
CAP参数 3个常量及标识 JOIN参数 3常量及标识
代码实现流程:
- 创建Stroke接口对象,实例BasicStroke对象
- 设置画笔 setStroke(Stroke)方法
大致例子:
import javax.swing.*;
import java.awt.*;
public class BrushTest extends JFrame {
public BrushTest(){
setBounds(400 ,300 ,300 ,230);
setDefaultCloseOperation(3);
add(new MyCanvas());
}
class MyCanvas extends Canvas{
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
Stroke[] s = {
new BasicStroke(10 , BasicStroke.CAP_ROUND ,BasicStroke.JOIN_ROUND),
new BasicStroke(10 , BasicStroke.CAP_BUTT , BasicStroke.JOIN_ROUND),
new BasicStroke(10 , BasicStroke.CAP_SQUARE , BasicStroke.JOIN_ROUND),
new BasicStroke(10 , BasicStroke.CAP_BUTT , BasicStroke.JOIN_BEVEL)
};
// 图形No.1
g2.setStroke(s[0]);
g2.drawLine(10,10 , 230,10);
g2.setStroke(s[1]);
g2.drawLine(10,30 , 230,30);
g2.setStroke(s[2]);
g2.drawLine(10,50 , 230,50);
// 图形No.2
//更改颜色
g2.setColor(Color.CYAN);
g2.setStroke(s[3]);
int[] x = {20 ,200 ,20 ,200},
y = {80 ,80 ,180 ,180};
g2.drawPolyline(x , y , 4);
}
}
public static void main(String[] args) {
new BrushTest().setVisible(true);
}
}
运行结果:
# 绘制文本
# 设置字体
Class Font
java.lang.Object java.awt.Font
Font类 封装字体的大小、样式等属性 构造方法
Font(String naem , int style , int size)
name: 字体名称 style: 字体样式 size: 字体大小
字体样式 | 常量 |
---|---|
普通 | PLAIN |
粗体 | BOLD |
斜体 | ITALIC |
粗体&斜体 | ITALIC | BOLD |
# 显示文字
Graphics2D提供了 drawString()方法 ,可以抛开 JLable类 写入窗体的方法
(Graphics2D | Graphics)drawString(String str , int x , int y) (Graphics2D )drawString(String str , float x , float y)
str: 文本 x: 坐标X y: 坐标Y
import javax.swing.*;
import java.awt.*;
//4.绘制文本
public class DrawTextTest extends JFrame {
public DrawTextTest() {
setBounds(400, 300, 230, 150);
setDefaultCloseOperation(3);
add(new Canvas() {
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
Font[] f = {
new Font("微软雅黑", Font.BOLD, 23),
new Font("微软雅黑", Font.ITALIC, 23),
new Font("微软雅黑", Font.ITALIC | Font.BOLD, 23)
};
g2.setFont(f[0]);
g2.drawString("Sanscan12" , 20 , 30);
g2.setFont(f[1]);
g2.drawString("Sanscan12" , 20 , 60);
g2.setFont(f[2]);
g2.drawString("Sanscan12" , 20 , 90);
}
});
}
public static void main(String[] args) {
new DrawTextTest().setVisible(true);
}
}
运行结果:
# 绘制图片
Graphics提供了 drawImage()方法,可以进行绘制图片处理图片,抛开 JLable类 写入窗体的方法
drawImage(Image img , int x , int y , ImageObserver observer)
img: 图片对象 x: 坐标X y: 坐标Y observer: 窗体/容器
# 图像处理
# 缩放
重写drawImage()方法,区别6个参数,要原有初始大小的图片
drawImage(Image img , int x , int y , int width , int height , ImageObserver observer)
width: 图片新宽度 height: 图片新高度
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//2.缩放
// Main类调用 该实例
public class SizeTest extends Canvas {
int W , H ;
Image image;
static int count = 0;
static JButton[] jb = {
new JButton("放大"),
new JButton("缩小")
};
public SizeTest(){
this.image = new ImageIcon("Image1.png").getImage();
this.W = image.getWidth(this);
this.H = image.getHeight(this);
Canvas c = this;
//添加响应
// 放大
jb[0].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count+=1;
c.repaint();
}
});
//缩小
jb[1].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count-=1;
c.repaint();
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(image , 0 , 0 ,W+count , H+count , this);
}
public static JButton[] getJButtonAll(){
return jb;
}
}
运行结果:
# 翻转
重写drawImage()方法,区别10个参数,水平垂直翻转的作用
drawlmage(Image img , int dx1 , int dy1 , int dx2 , int dy2 , int sx1 , int sy1 , int sx2 , int sy2 , ImageObserver observer)
dx1/dy1: 目标矩形对应角XY坐标 dx2/dy2: 目标矩形对应角XY坐标 sx1/sy1: 源矩形左上角XY坐标 sx2/sy2: 源矩形右下角XY坐标
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//3.翻转
//在Main类调用 该实例
public class TurnTest extends Canvas{
static JButton[] jb = {
new JButton("水平"),
new JButton("垂直")
};
Image image ;
int sx1,sy1,sx2,sy2; //源矩形左上,右下
int dx1,dy1,dx2,dy2; //目标矩形
int origin , width , hight;
public TurnTest(){
//初始化数据
image = new ImageIcon("Image1.png").getImage();
origin = 0;
width = image.getWidth(this);
hight = image.getHeight(this);
dx1 = sx1 = origin;
dy1 = sy1 = origin;
dx2 = sx2 = width;
dy2 = sy2 = hight;
Canvas c = this;
//水平
jb[0].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//dx1右上获取 宽(width-width)
dx1 = Math.abs(dx1 - width);
//dx2左下获取 宽 (0-width)
dx2 = Math.abs(dx2 - width);
c.repaint();
}
});
//垂直
jb[1].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//dy1 右上获取 高 (0-hight)
dy1 = Math.abs(dy1 - hight);
//dy2 左下获取 高 (higth - hight)
dy2 = Math.abs(dy2 - hight);
c.repaint();
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(image ,
dx1 , dy1 ,dx2 , dy2 , //目标矩形
sx1 , sy1 , sx2 , sy2 , //源矩形
this);
}
public static JButton[] getJButtonAll(){
return jb;
}
}
运行结果:
# 旋转
重写drawImage()方法,区别6个参数,旋转的前提需要调用Graphics2D类的rotate()方法,进行旋转
drawImage(Image img , int x , int y , int width , int height , ImageObserver observer)
方法 rotate(double thete) thete:旋转弧度
参数的弧度值可以使用Math类的toRadians()方法将角度转换为弧度(近似值)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//2.旋转
// Main类调用 该实例
public class WhirlTest extends Canvas {
int W , H ;
Image image;
static int count = 0;
static JButton[] jb = {
new JButton("左转"),
new JButton("右转")
};
public WhirlTest(){
this.image = new ImageIcon("Image1.png").getImage();
this.W = image.getWidth(this);
this.H = image.getHeight(this);
Canvas c = this;
//添加响应
// 左
jb[0].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count++;
c.repaint();
}
});
//右
jb[1].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count--;
c.repaint();
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
//toRadians:以度为单位的角度转换为以弧度(近似值)
g2.rotate(Math.toRadians(count));
g2.drawImage(image , 0 , 0 ,W , H , this);
}
public static JButton[] getJButtonAll(){
return jb;
}
}
运行结果:
# 倾斜
重写drawImage()方法,区别6个参数,旋转的前提需要调用Graphics2D类的shear()方法,实现倾斜
drawImage(Image img , int x , int y , int width , int height , ImageObserver observer)
方法 shear(double shx , double shy) shx: 水平倾斜量 ; shy: 垂直倾斜量
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
//5.翻转
//在Main类调用 该实例
public class TiltTest extends Canvas{
int W , H ;
double X , Y;
static boolean Narrow = false;
static JButton[] jb = {
new JButton("<--︿"),
new JButton("﹀-->")
};
Image image ;
public TiltTest(){
//初始化数据
image = new ImageIcon("Image1.png").getImage();
W = image.getWidth(this);
H = image.getHeight(this);
X = Y = 0;
Canvas c = this;
//判断Alt键是否按下
System.out.println("通过点击Alt键,控制倾斜 X 或 Y 轴");
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) { }
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyText(e.getKeyCode()) == "Alt"){
if (Narrow){
Narrow = false;
System.out.println("目前倾斜X轴");
}else {
Narrow = true;
System.out.println("目前倾斜Y轴");
}
}
}
@Override
public void keyReleased(KeyEvent e) { }
});
//<--
jb[0].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (Narrow){
Y -= 0.05;
}else {
X -= 0.05;
}
c.repaint();
}
});
//-->
jb[1].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (Narrow){
Y += 0.05;
}else {
X += 0.05;
}
c.repaint();
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
//主要代码
g2.shear(X , Y);
g2.drawImage(image , 0 , 0 ,W , H , this);
}
public static JButton[] getJButtonAll(){
return jb;
}
}
运行结果:
# 处理Main执行
以上 图片处理 代码需要Main类执行
import javax.swing.*;
import java.awt.*;
//1.图形显示
public class Main extends JFrame {
//public JButton
// jb1 = new JButton("+"),
// jb2 = new JButton("-");
//public Canvas canvas = null;
public Main(Canvas c , JButton jb1 ,JButton jb2){
setBounds(400 , 300 , 666 , 600);
setDefaultCloseOperation(3);
JPanel jp = new JPanel();
jp.add(jb1);
jp.add(jb2);
add(jp , BorderLayout.SOUTH);
add(c);
}
public static void main(String[] args) {
/* 自行实例
* 1.GraphTest //显示图片
* 2.SizeTest //放大与缩小
* 3.TurnTest //翻转
* 4.WhirlTest //旋转
* 5.TiltTest //倾斜
* */
Canvas canvas = new TiltTest();//更改实例对象即可
JButton[] jb = TiltTest.getJButtonAll();//更改类
new Main(canvas , jb[0] , jb[1]).setVisible(true);
}
}
图片流转换
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
/**
* 将二进制流转换成图片文件
* @author 晚风工作室 www.soservers.com
*
*/
public class ImgErToFileUtil {
/**
* 将接收的字符串转换成图片保存
* @param imgStr 二进制流转换的字符串
* @param imgPath 图片的保存路径
* @param imgName 图片的名称
* @return
* 1:保存正常
* 0:保存失败
*/
public static int saveToImgByStr(String imgStr,String imgPath,String imgName){
try {
System.out.println("===imgStr.length()====>" + imgStr.length()
+ "=====imgStr=====>" + imgStr);
} catch (Exception e) {
e.printStackTrace();
}
int stateInt = 1;
if(imgStr != null && imgStr.length() > 0){
try {
// 将字符串转换成二进制,用于显示图片
// 将上面生成的图片格式字符串 imgStr,还原成图片显示
byte[] imgByte = hex2byte( imgStr );
InputStream in = new ByteArrayInputStream(imgByte);
File file=new File(imgPath,imgName);//可以是任何图片格式.jpg,.png等
FileOutputStream fos=new FileOutputStream(file);
byte[] b = new byte[1024];
int nRead = 0;
while ((nRead = in.read(b)) != -1) {
fos.write(b, 0, nRead);
}
fos.flush();
fos.close();
in.close();
} catch (Exception e) {
stateInt = 0;
e.printStackTrace();
} finally {
}
}
return stateInt;
}
/**
* 将二进制转换成图片保存
* @param imgStr 二进制流转换的字符串
* @param imgPath 图片的保存路径
* @param imgName 图片的名称
* @return
* 1:保存正常
* 0:保存失败
*/
public static int saveToImgByBytes(File imgFile,String imgPath,String imgName){
int stateInt = 1;
if(imgFile.length() > 0){
try {
File file=new File(imgPath,imgName);//可以是任何图片格式.jpg,.png等
FileOutputStream fos=new FileOutputStream(file);
FileInputStream fis = new FileInputStream(imgFile);
byte[] b = new byte[1024];
int nRead = 0;
while ((nRead = fis.read(b)) != -1) {
fos.write(b, 0, nRead);
}
fos.flush();
fos.close();
fis.close();
} catch (Exception e) {
stateInt = 0;
e.printStackTrace();
} finally {
}
}
return stateInt;
}
/**
* 二进制转字符串
* @param b
* @return
*/
public static String byte2hex(byte[] b) // 二进制转字符串
{
StringBuffer sb = new StringBuffer();
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1) {
sb.append("0" + stmp);
} else {
sb.append(stmp);
}
}
return sb.toString();
}
/**
* 字符串转二进制
* @param str 要转换的字符串
* @return 转换后的二进制数组
*/
public static byte[] hex2byte(String str) { // 字符串转二进制
if (str == null)
return null;
str = str.trim();
int len = str.length();
if (len == 0 || len % 2 == 1)
return null;
byte[] b = new byte[len / 2];
try {
for (int i = 0; i < str.length(); i += 2) {
b[i / 2] = (byte) Integer
.decode("0X" + str.substring(i, i + 2)).intValue();
}
return b;
} catch (Exception e) {
return null;
}
}
}