对不起,让大家久等了,继续写blog。

今天我们继续研究位图的任意形变,今天的主要目的就是从外部加载一张图片,然后分割成两个三角形。当然了,分割成两个三角形是远远不够的,这一点,我们在后面会讲到。

从外部加载一张图片很简单,使用Loader类就可以轻松完成了。不过要注意的是这里是Loader类,在包flash.display下,而不是flash.net下的URLLoader类。这个类使用很简单,如下(为了简单,这就不写那些条条框框了,直接写在时间轴上了,所有的代码都在第一帧):

// 这个是我们要load的图片
var url:String = 'green.jpg';

//这个是用来保存位图数据的
var bmd:BitmapData = null;

// load方法
function Load():void {
    var req:URLRequest = new URLRequest(url);
    var loader:Loader = new Loader();
    // 添加事件侦听
    ConfigureListeners(loader.contentLoaderInfo);
    try {
        // 加载图片
        loader.load(req);
        // 如果你要在舞台上显示出来
        // 可以添加下面的代码
        // this.addChild(loader);
    } catch (err:Error) {
    }
}

function ConfigureListeners(dispatcher:IEventDispatcher):void {
    dispatcher.addEventListener(Event.COMPLETE, CompleteHandler);
}

// 事件控制函数
function CompleteHandler(evt:Event):void {
    var ld:Loader = Loader(evt.target.loader);
    var info:LoaderInfo = LoaderInfo(ld.contentLoaderInfo);
    // 保存位图数据
    bmd = new BitmapData(info.width, info.height);
    bmd.draw(info.content);
}

要分割成三角行,我们实现的方式是,先绘制一个三角形,然后用位图来填充,绘制和填充也很简单:

// bw是我们最后绘制的三角形的宽
// bh是我们最后绘制的三角形的高
// 我这里的图片宽高比是4:3,为了简单,就这样直接指定了
var bw:Number = 280, bh:Number = 210;

// 给出三个点,绘制三角形
// 并使用位图数据填充
function drawTriagle(pa:Object, pb:Object, pc:Object):Shape{
    var r = new Shape();
    // 为了清晰可见,你可以给三角形画一个边框
    // 加上下面一行代码即可
    // r.graphics.lineStyle(0, 0xccff00);
    var m:Matrix = new Matrix();
    // 由于图片比绘制的三角形的宽高要大
    // 需要对其进行缩放处理
    var sx = bw / bm.width;
    var sy = sx;
    m.scale(sx, sy);
    // 使用位图填充三角形
    r.graphics.beginBitmapFill(bm.bitmapData, m, false, true);
    r.graphics.moveTo(pa.x, pa.y);
    r.graphics.lineTo(pb.x, pb.y);
    r.graphics.lineTo(pc.x, pc.y);
    r.graphics.lineTo(pa.x, pa.y);
    r.graphics.endFill();
    // 返回当前绘制的三角形
    return r;
}

还差一步,就是要把这两步连接起来,我们再来写一个非常简单的split方法,当位图加载完成后,调用split方法。通过split方法,绘制两个三角形:

var triangle_a:DisplayObject = null;
var triangle_b:DisplayObject = null;

// 这个方法需要在位图加载之后调用
function split(){
    var p1 = {x: 0, y: 0};   // 左上角
    var p2 = {x: bw, y: 0};  // 右上角
    var p3 = {x: 0, y: bh};  // 左下角
    var p4 = {x: bw, y: bh}; // 右下角
    
    // 以p2和p3为分割线,切割成两个三角形
    // 绘制完成后添加到舞台上
    triangle_a = DisplayObject(drawTriagle(p1, p2, p4));
    this.addChild(triangle_a);

    triangle_b = DisplayObject(drawTriagle(p2, p4, p5));
    this.addChild(triangle_b);
}

这样我们就完成了把位图分割成两个三角形的任务,下面的任务是对两个三角形形变,并对这两个三角形进行拼接,以达到对位图任意形变的目的,这个我们在下一篇中再讲。

7 Comments

  1. 正在研究,原理就是一个拉伸后的4变形分割为2个三角形进行填充对吧?

  2. 忙的把这茬儿给忘了,基本上就是这个思想,不过这个矩阵的算法我这里还有点问题,分割为多个矩形的时候位置有点偏差,有空再看看……

  3. 快点写吧,我还是研究不出来,分成若干三角形后,不知道该怎么办了,希望看到这样讲解原理的好文章~

  4. 呃,好,我有空就继续研究~形变都没什么问题,就是坐标偏移还有点问题~

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.