远程加载多个方形头像+合图+合批+圆形裁剪

上一次发布 多个方形头像遮罩圆形头像+合批,要求图片事先组成一个合图,但是实际使用中图片往往是一张一张的零散图如下:
1710221218570
我们需要实现,远程下载合图功能。
下载及合图代码如下:

import { _decorator, Component, Node, Texture2D, Vec2, SpriteFrame, resources, ImageAsset, v2 } from ‘cc’;

import { TextureManager } from ‘./TextureManager’;

const { ccclass, property } = _decorator;

@ccclass(‘MergeManager’)

export class MergeManager {

//图片行数

_rowMax:number = 0;

//图片列数

_colMax:number = 0;

//图片行计数

_rowCount:number = 0;

//图片列计数

_colCount:number = 0;

//图片计数

_imageCount:number = 0;

//单个图片宽

_imageWidth:number = 0;

//单个图片高

_imageHeight:number = 0;

//下载路径

_paths:string[];

_mergeTexture:Texture2D;

_imageMap = new Map();

_loaded:boolean = false;

onLoaded:Function;

/*

    paths:路径数组

    col:列数

    row:行数

    imageWidth:单个图片宽度

    imageHeight:单个图片高度

*/

constructor(paths:string[],col:number,row:number,imageWidth:number,imageHeight:number)

{

    this._paths = paths;

    this._colMax = col;

    this._rowMax = row;

    this._imageWidth = imageWidth;

    this._imageHeight = imageHeight;

}



init()

{

    let array_length = this._imageWidth*this._colMax *this._imageHeight* this._rowMax *4;

    let imageData = new Uint8Array(array_length);

    for(let i = 0; i < imageData.length;i++)

    {

        if(i%4 == 3)

        {

            imageData[i] = 255;

        }

        else

        {

            imageData[i] = 255;

        }

    }

    this._mergeTexture = TextureManager.createTexture(imageData,this._imageWidth*this._colMax,this._imageHeight* this._rowMax);

    for(let path of this._paths)

    {

        this.loadImage(path);

    }

}

loadImage(path:string,loaded?:Function)

{

        resources.load(path, ImageAsset, (err, image) => {

        if(err)

        {

            console.error(err);

        }

        else

        {

            let frame = SpriteFrame.createWithImage(image);

            let add:any = frame.texture;

            let pos:Vec2 = v2(this._colCount*this._imageWidth,this._rowCount*this._imageHeight);

            this._imageMap.set(path,pos);

            this._colCount++;

            if(this._colCount == this._colMax)

            {

                this._colCount = 0;

                this._rowCount++;

            }

            this._mergeTexture = TextureManager.addImage(this._mergeTexture,add,pos);

            //let frame1 = new SpriteFrame();

        }

        this._imageCount++;

        if(this._imageCount == this._paths.length)

        {

            this._loaded = true;

            this.onLoaded&&this.onLoaded(this._mergeTexture)

        }

    });

}

}
这样 就可以创建生成一个张合图

合图实现代码:
import { _decorator, Component, Node, Texture2D, gfx, Vec2, v2, ImageAsset } from ‘cc’;

const { ccclass, property } = _decorator;

export class TextureManager {

//通过data创建texture

public static createTexture(imgData:any,width:number,height:number):Texture2D

{

   //默认一张白色纹理

   let tex = new Texture2D();

   // /包含 RGBA 四通道的 32 位整形像素格式:RGBA8888。 一字节8位

   tex.reset({width: width, height: height, format: Texture2D.PixelFormat.RGBA8888, mipmapLevel: 0 });

   tex.uploadData(imgData, 0, 0);

   // 更新 0 级 Mipmap。

   tex.updateImage();

   return tex;

}

//扩展图片

public static expandImage(imgData:Uint8Array,width:number,height:number,expand:number = 0):Uint8Array

{

   let buffer = new Uint8Array(imgData.length + 4 * (expand * width * 2 + expand * height * 2 + height*width*4));  

   let row = 0;

   let col = 0;

   let img_index = 0;

   let new_width =  width + expand * 2;

   let new_height = height + expand * 2;

   let color_value = 0;

   for(let index =0;index< buffer.length;index  = index + 4)

   {

       if(row < expand)

       {

        buffer[index] = color_value;

        buffer[index+1] = color_value;

        buffer[index+2] = color_value;

        buffer[index+3] = color_value;

       }

       else if(row >= height + expand)

       {

           buffer[index] = color_value;

           buffer[index+1] = color_value;

           buffer[index+2] = color_value;

           buffer[index+3] = color_value;

       }

       else

       {

           if(col < expand)

           {

                buffer[index] = color_value;

                buffer[index+1] = color_value;

                buffer[index+2] = color_value;

                buffer[index+3] = color_value;

           }

           else if(col >= width + expand)

           {

                buffer[index] = color_value;

                buffer[index+1] = color_value;

                buffer[index+2] = color_value;

                buffer[index+3] = color_value;

           }

           else

           {

               buffer[index] = imgData[img_index];

               buffer[index+1] = imgData[img_index+1];

               buffer[index+2] = imgData[img_index+2];

               buffer[index+3] = imgData[img_index+3];

               img_index = img_index + 4;

           }

       }

       col++;

       if(col >= new_width)

       {

           col = 0;

           row++;

       }

   }

   return buffer;

}

public static addImage(oriTex:Texture2D,addTex:Texture2D,offset:Vec2 = v2(0,0))

{

    let oriData = this.readPixelsForTexture(oriTex);

    let addData =  this.readPixelsForTexture(addTex);  

    let row = 0;

    let col = 0;

    let addIndex = 0;

    //console.log(addData);

    for(let index =0;index< oriData.length;index  = index + 4)

    {  

       

        if(col >= offset.x && col < addTex.width +  offset.x && row >= offset.y && row < addTex.height +  offset.y )

        {

            let alpha = addData[addIndex+3]

            oriData[index] = addData[addIndex];

            oriData[index+1] = addData[addIndex+1];

            oriData[index+2] = addData[addIndex+2];

            oriData[index+3] = alpha;

            addIndex  += 4;

        }

        col++;

        if(col == oriTex.width)

        {

            col = 0;

            row++;

            /*

            let alpha = addData[addIndex+3]

            oriData[index] = addData[addIndex];

            oriData[index+1] = addData[addIndex+1];

            oriData[index+2] = addData[addIndex+2];

            oriData[index+3] = alpha;

            addIndex  += 4;*/

        }

    }  

    return this.createTexture(oriData,oriTex.width,oriTex.height);

}

//读取数组

public static readPixelsForTexture(tex: any):Uint8Array {

   const gfxTexture = tex.getGFXTexture();

   if (!gfxTexture) {

       return null;

   }

   //数组长度

   const needSize = 4 * tex.width * tex.height;

   let buffer = new Uint8Array(needSize);

   const gfxDevice = tex._getGFXDevice();

   const bufferViews: ArrayBufferView[] = [];

   const regions: gfx.BufferTextureCopy[] = [];

   const region0 = new gfx.BufferTextureCopy();

   

   //数组设置起始和宽高

   region0.texOffset.x = 0;

   region0.texOffset.y = 0;

   region0.texExtent.width = tex.width;

   region0.texExtent.height =tex.height;

   //copy数据

   regions.push(region0);

   bufferViews.push(buffer);

   gfxDevice?.copyTextureToBuffers(gfxTexture, bufferViews, regions);

   return buffer;

}
最终实现效果:
1710221819398
源码地址:http://store.cocos.com/app/detail/4025

1赞