java写3d动画视频_Web3D中文站

在JMFMovieScreen中,实现把四边形顶点与纹理坐标相链接的代码如下:

TexCoord2f q = new TexCoord2f();

q.set(0.0f, 0.0f);

plane.setTextureCoordinate(0, 3, q);

//纹理坐标(0,0)-->四边形左上点(p3)

q.set(1.0f, 0.0f);

plane.setTextureCoordinate(0, 2, q);

// (1,0) -->右上(p2)

q.set(1.0f, 1.0f);

plane.setTextureCoordinate(0, 1, q);

// (1,1) -->右下(p1)

q.set(0.0f, 1.0f);

plane.setTextureCoordinate(0, 0, q);

// (0,1) -->左下(p0)

这里的平面对象代表了四边形。

更新图像

前面已经提到,一个TimeBehavior对象被建立以每隔40毫秒调用一次JMFMovieScreen的nextFrame()方法。而nextFrame()又调用JMFSnapper对象的getFrame()方法来以一个BufferedImage对象方式检索当前动画帧。该BufferedImage对象被指派给ImageComponent2D对象,然后用于四边形的材质。nextFrame()的代码如下所示:

//全局变量

private Texture2D texture; //由四边形使用

private ImageComponent2D ic;

private JMFSnapper snapper;

//快照该动画

private boolean isStopped = false;

//动画停止了吗?

public void nextFrame()

{

if (isStopped) //动画已经停止

return;

BufferedImage im = snapper.getFrame();

//获取当前帧

if (im != null) {

ic.set(im); //把该帧指派给ImageComponent2D

texture.setImage(0,ic);

//使成为该形状的材质

}

else

System.out.println("Null BufferedImage");

}

JMFSnapper对象snapper是在JMFMovieScreen的构造器中创建的:

//装载并播放动画

snapper = new JMFSnapper(movieFnm);

JMFSnapper中的简单接口隐藏了用于播放动画和从动画中提取帧的JMF代码的复杂性。在本文的第二部分里,JMFSnapper类为一个使用QuickTime for Java的版本所取代,且JMFMovieScreen类也作了最少的修改。

5.管理动画

JMF为存取特定的动画帧提供了一种高级存取方式。下面的代码片断显示了该高级方式的主要组成,我略去了其中有关错误检测及异常处理的部分。

//在realized状态下,创建一个动画播放器

URL url = new URL("file:" + movieFnm);

Player p = Manager.createRealizedPlayer(url);

//生成一个帧放置器

FramePositioningControl fpc = (FramePositioningControl) p.getControl("javax.media.control. FramePositioningControl");

//创建一个帧抓取器

FrameGrabbingControl fg = (FrameGrabbingControl) p.getControl("javax.media.control.FrameGrabbingControl");

//要求改变到一个prefetched 态

p.prefetch();

//一直等待,直到播放器处于那种状态...

//移动到具体的某帧,例如第100帧

fpc.seek(100);

//取得当前帧的一个快照

Buffer buf = fg.grabFrame();

//取得它的视频格式细节

VideoFormat vf = (VideoFormat) buf.getFormat();

//用视频格式初始化BufferToImage

BufferToImage bufferToImage =new BufferToImage(vf);

//把缓冲区数据转化成一幅图像

Image im = bufferToImage.createImage(buf);

//指定想得到的BufferedImage的格式

BufferedImage formatImg =

new BufferedImage(

FORMAT_SIZE, FORMAT_SIZE,

BufferedImage.TYPE_3BYTE_BGR);

//把该图像转化成一个BufferedImage

Graphics g = formatImg.getGraphics();

g.drawImage(im, 0, 0,

FORMAT_SIZE, FORMAT_SIZE, null);

g.dispose();

一个媒体播放器从创建到开始播放共经历6种状态。处于realized态的播放器知道如何对其数据进行着色,所以在要求时可以提供可视化组件和控件。我用了两个控件:FramePositioningControl 和FrameGrabbingControl。FramePositioningControl提供seek()和skip()等方法,用于在一个动画中移动以查找一个特别的帧。FrameGrabbingControl提供了方法grabFrame(),它可以从动画的视频轨道中抓取当前帧。

为使这些控件工作,播放器必须实现从realized 态转入prefetched 态。这可以使播放器为进行媒体播放作好准备,并使媒体数据装入。

对于prefetch()的调用是异步的,这意味着我的代码必须包含一个等待周期,直到完成一个变换状态为止。标准的JMF编码方案是实现一个waitForState()方法,它可以停止代码的执行,直到一个状态改变事件唤醒它。

要抓取的帧可以用seek()方法在轨道中定位,然后调用grabFrame()方法实现帧的抓取。编码中必须经历多个转换步骤来把抓取的缓冲对象转怀蒍MFMovieScreen要求的BufferedImage对象。注意,BufferedImage对象使用了TYPE_3BYTE_BGR格式,这种格式对于该程序中的Java 3D部分通过引用方式使用纹理是必需的。

Sun的JMF站点 包括了一些有用的小例子,其中Seek.java一例说明了如何使用FramePositioningControl来遍历一个动画

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值