java基础——图形,图像,音频

	   今天来讲讲java的图形,图像与音频。

背景知识:Component类有一个方法public void paint(Graphics
g),程序可以在其子类中重写这个方法,当程序运行时,java运行环境会用Graphics2D(Graphics的子类)将参数g实例化,g就可以在重写paint方法的组件上绘制图形,图像。组件都是矩形形状,组件本身有一个默认的坐标,是左上角(0,0),如果一个组件的宽时200,高80,那么坐标系中,x的最大值是200,y的最大值是80.
java提供的Graphics2D有强大的二维图形处理能力,它是Graphics的子类,它把直线,圆形看做一个对象绘制。丫就是说想用一个Graphics2D类型的画笔画一个圆的话,就必须先创建一个圆的对象。
画笔分别使用draw和fill方法来绘制和填充一个图形。

目录

  1. 绘制基本图形

  2. 变换图形

  3. 图形的布尔运算

  4. 绘制钟表

  5. 绘制图像

  6. 播放音频

  7. 应用举例

  8. 小结

    		一 ,绘制基本图形
    

1.直线

new Line2D.Double(double x1,double y1,double x2,double y2)
创建起点x1,y1到x2,y2的直线

2.矩形

new Rectangle2D.Double(double x,double y,double w,double h)
创建一个左上角是(x,y),宽w,高h的矩形对象

3.圆角矩形

new RoundRectangle2D.Double(double x,double y,double w,double h,double
arcw,double arch) 左上角坐标是x,y,宽w,高h,圆角的长轴和短轴分别是arcw和arch的圆角矩形对象。
这里圆角的长轴是指内接的椭圆的长轴和短轴

4.椭圆

newEllipse2D.Double(double x,double y,double w,double h)
创建一个外接矩形的左上角坐标是x,y,宽w,高h的椭圆对象。

5.绘制圆弧

new Arc2D.Double(double x,double y,double w,double h,double
start,double extend,int type)
创建圆弧对象,圆弧就是椭圆的一部分,参数x,y,w,h指定椭圆的位置和大小,参数start, extend的单位都是度,start,extend表示从start的角度开始逆时针或者顺时针方向画出extend度的弧,当extend是正值时为逆时针,否则是顺时针。比如起始角度start是0就是三点钟方向。type取值决定弧是开弧,弓弧,饼弧。弧的类型。

6.绘制文本

Graphics2D对象调用drawString(String s,int x,int y)方法从参数x,y指定的坐标位置处,从左向右绘制参数s指定的字符串

7.绘制二次曲线和三次曲线

二次
QuadCurve2D curve=new
QuadCurve2D.Double(50,30,10,10,50,100);创建一条端点是50,30和50,100,控制点是10,10的二次曲线。
三次
CubicCurve2D curve=new
CubicCurve2D.Double(50,30,10,10,100,100,50,100); 端点是50,30 50,100 控制点是10,10 100,100

8.绘制多边形

Polygon polygon=new Polygon();
创建空多边形,然后调用addPoint(int x,int y)向多边形添加顶点。

图形对象调用setFrame方法(x1,y1,x2,y2)可以重新设置位置。。

			二,变换图形

背景:需要平移,缩放或者旋转一个图形,可以使用AffineTransfrom类来实现对图形的这些操作。

  1. 首先使用AffineTransform类创建一个对象;
    AffineTransfrom trans=new AffineTransform();
    对象trans使用下列的三个方法来实现对图形的变换操作

1.translate(double a,double b) 将图形在x轴方向上移动a个像素单位,a是正值时向右移动,是负值向左移动;y轴移动b个像素单位,b为正值向下移动,是负值向上移动。
2.scale(double a,double b) 将图形在x轴缩放a倍,y轴缩放b倍
3.rotate(double number,double x,double y) 将图形沿着顺时针或者逆时针方向以(x,y)为轴点旋转number个弧度。

  1. 进行需要的变换,比如要把一个矩形绕点100,100顺时针旋转60度,那么需要先做好准备。

    trans.rotate(60.0*3.1415926/180,100,100);

  2. 把Graphics对象,比如g_2d,设置为具有trans功能的“画笔”
    g_2d.setTransform(trans);
    假如rect是一个矩形对象,g_2d.draw(rect)画的就是旋转后的矩形。
    顺序不可以颠倒

     		三,图形的布尔运算
    

通过基本图形的布尔运算可以得到更复杂的图形。T1,T2两个图形。
T1与T2的布尔与的结果是两个图形的重叠部分。
T1与T2的布尔或的结果是两个图形的合并。
T1与T2的布尔差的结果是T1去掉T1和T2重叠的部分
T1与T2异或的结果是两个图形的非重叠部分
两个图形进行布尔运算前,必须分别用这两个图形创建两个Area区域对象,例如

Area a1=new Area(T1);
Area a2=new Area(T2);

a1.add(a2) a1就变成a1a2经过布尔或运算后的图形区域了。可以用Graphics2D对象g来绘制或者填充一个Area对象。区域
g.draw(a1);
g.fill(a1);

Area类的常用方法

public  void add(Area r);    与参数或
public  void intersect(Area r);   与参数与
public  void exclusiveOr(Area rhs); 与参数异或
public  void subtract(Area rhs)   与参数差


基本过程
1.创建两个图形对象
Ellipse2D ellipse=new Ellipse2D.Double(0,2,80,80);
Rectangle2D rect=new Rectangle2D.Double(40,2,80,80);
Area a1=new Area(ellpise);
Area a2=new Area(rect);
a1.intersect(a2);

			 绘制钟表

下面利用多线程技术绘制钟表,该钟表可以显示当前本机的时间,在这里需要用到一个数学公式,如果一个圆的圆心是0,0,那么对于给定圆上的一点x,y,该点按顺时针方向旋转阿尔法弧度后的坐标是m,n,由下列公式计算:阿尔法是弧度。。
m=xcos(阿尔法)-ysin(阿尔法);
n=ycos(阿尔法)+xsin(阿尔法);
具体实例见例一

			绘制图像

组件上可以显示图像,可以首先使用Icon类的子类ImageIcon创建封装cat.jpg图像文件的IconImage对象。
Icon icon =new ImageIcon(“cat.jpeg”);
然后button.setIcon(icon);
除了上述方法还有使用Graphics绘制图像,步骤如下。

  • 加载图像
    java运行环境提供了一个Toolkit对象,任何一个组件调用getToolkit方法可以返回这个对象的引用,Toolkit类的对象调用Image getImage(String filename)或者File file。可以返回一个Image对象,封装着参数指定的图像文件。

  • 绘制图像
    图像被加载后,即被封装到Image实例中,就可以在paint()方法中绘制它了,Graphics类提供了几个名为drawImage()的方法用于绘制图像,都是在指定位置绘制一幅图像,不同之处在于确定图像的大小,解释图像中透明部分的方式,以及是否支持图像的剪辑和拉伸。学会使用最基本的drawImage()。可以很容易的使用另外的几个方法。
    public boolean drawImage(Image img,int x,int y,ImageObserver obsserver);
    img是被绘制的图像,x,y是绘制指定图像的矩形的左上角所处的位置,observer是加载图像时的图像观察器。
    如果组件的高,宽,设计不合理,可能出现有些图像的某些部分不能完全绘制到组件上,为了克服这个缺点,可以使用drawImage()的另一个方法
    public boolean drawImage(Image img,int x,int y,int width,int height,ImageObserver observer).该方法在矩形内绘制加载的图像,参数img是被绘制的Image对象,x,y是要绘制指定图像的矩形的左上角所处的位置,width和height指定矩形的宽和高。observer是加载图像时的图像观察器。
    实现了ImageObserver接口类创建的对象都可以作为图像观察器,java所有默认组件都已经实现了该接口,因此任何一个组件都可以作为图像观察器。
    JFrame对象可用setIconImage(Image img)方法设置窗口左上角的图像,java 窗口默认的图标是一个咖啡杯。

     			播放音频
    

用java可以编写.au,.aiff,.wav,.midi,.rfm.格式的音频程序,假设音频文件hello.wav位于应用程序当前目录,播放音频的步骤如下

  • 创建File对象
    File musicFile=new File(“hello.wav”);

  • 获取URI对象
    URI uri=musicFile.toURI();

  • 获取URL对象
    URI URL=uri.toURL();

  • 创建音频对象
    AudioClip clip=Accept.newAudioClip(url);

  • 播放,循环,停止
    clip.play()开始播放
    clip.loop(循环播放)
    clip.stop(停止播放)

     			应用举例
    
  • 制作JPG图像

  • 弹奏音节

  • 绘制钟表
    源代码
    Example.java

package 绘制钟表;
import javax.swing.JFrame;
public class Example {
 public  static void main(String args[])
 {
  javax.swing.JFrame win=new javax.swing.JFrame();
  win.setSize(400,400);
  win.add(new Clock());
  win.setVisible(true);
 }
}
Clock.java

```java
package 绘制钟表;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.util.Date;
public class Clock extends Canvas implements ActionListener
{
 Date date;
 javax.swing.Timer secondTime;
 int hour,munite,second;
 Line2D secondLine,muniteLine,hourLine;
 int a,b,c;
 double pointSX[]=new double[60];     //表示秒针端点坐标的数组
 double pointSY[]=new double[60];
 double pointMX[]=new double[60];    //分针
 double pointMY[]=new double[60];
 double pointHX[]=new double[60];    //时针
 double pointHY[]=new double[60];
 Clock()
 {
  secondTime=new javax.swing.Timer(1000, this);     //一秒钟以后就触发,监听事件。
  pointSX[0]=0;
  pointSY[0]=-100;
  pointMX[0]=0;
  pointMY[0]=-90;
  pointHX[0]=0;
  pointHY[0]=-70;
  double angle=6*Math.PI/180;
  for(int i=0;i<59;i++)
  {
   pointSX[i+1]=pointSX[i]*Math.cos(angle)-Math.sin(angle)*pointSY[i];
   pointSY[i+1]=pointSY[i]*Math.cos(angle)+Math.sin(angle)*pointSX[i];
   pointMX[i+1]=pointMX[i]*Math.cos(angle)-Math.sin(angle)*pointMY[i];
   pointMY[i+1]=pointMY[i]*Math.cos(angle)+Math.sin(angle)*pointMX[i];
   pointHX[i+1]=pointHX[i]*Math.cos(angle)-Math.sin(angle)*pointHY[i];
   pointHY[i+1]=pointHY[i]*Math.cos(angle)+Math.sin(angle)*pointHX[i];
  }
  for(int i=0;i<60;i++)
  {
   pointSX[i]=pointSX[i]+120;  //坐标平移
   pointSY[i]=pointSY[i]+120;
   pointMX[i]=pointMX[i]+120;
   pointMY[i]=pointMY[i]+120;
   pointHX[i]=pointHX[i]+120;
   pointHY[i]=pointHY[i]+120;
  }
  secondLine=new Line2D.Double(0,0,0,0);
  muniteLine=new Line2D.Double(0,0,0,0);
  hourLine=new Line2D.Double(0,0,0,0);
  secondTime.start();    //秒针开始计时
 }
 public void paint(Graphics g)
 {
  for(int i=0;i<60;i++)
  {
   int m=(int)pointSX[i];
   int n=(int)pointSY[i];
   if(i%5==0)
   {
    g.setColor(Color.red);
    g.fillOval(m-4, n-4, 8, 8);
   }
   else
   {
    g.setColor(Color.blue);
    g.fillOval(m-2, n-2, 4, 4);
   }
  }
  g.fillOval(115, 115, 10, 10);
  Graphics2D g_2d=(Graphics2D)g;
  g_2d.setColor(Color.red);
  g_2d.draw(secondLine);
  BasicStroke bs=new BasicStroke(3f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
  g_2d.setStroke(bs);
  g_2d.setColor(Color.blue);
  g_2d.draw(muniteLine);
  bs=new BasicStroke(6f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER);
  g_2d.setStroke(bs);
  g_2d.setColor(Color.black);
  g_2d.draw(hourLine);
 }
 @Override
 public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  if(e.getSource()==secondTime)
  {
   date=new Date();
   String s=date.toString();
   hour=Integer.parseInt(s.substring(11,13));
   munite=Integer.parseInt(s.substring(14,16));
   second=Integer.parseInt(s.substring(17,19));
   int h=hour%12;
   a=second;
   b=munite;
   c=h*5+munite/12;
   secondLine.setLine(120,120,(int)pointSX[a],(int)pointSY[a]);
   muniteLine.setLine(120,120,(int)pointMX[b],(int)pointMY[b]);
   hourLine.setLine(120,120,(int)pointHX[c],(int)pointHY[c]);
   repaint();
  }
 }
}

结果截图
在这里插入图片描述

			小结
  1. 可以使用Graphics类或者其子类Graphics2D类来绘制各种基本图形,图像。
  2. 在应用程序中可以播放.au,.aiff,.wav,.midi,.rfm格式的音频。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Devin Dever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值