목차
为什么需要使用图集
web开发
游戏开发
工具设计
开始编写脚本
脚本IO
遍历文件生成节点树
获取新的图集位置信息
웹 개발🎜웹 개발에서는 브라우저에 그림이 표시될 때마다 요청해야 합니다. 서버 리소스입니다.🎜🎜예를 들어 🎜3 4k🎜의 각 요청과 🎜12k의 한 요청🎜 사이에는 근본적인 차이가 있으며, 대부분의 경우 하나의 요청은 🎜3 * 4k🎜가 아닙니다.🎜🎜아틀라스 사용 리소스 로딩을 최적화하고 웹사이트 성능을 향상할 수 있습니다. 🎜

게임 개발

🎜게임 개발에서는 일반적으로 아틀라스를 사용하는 것이 중요합니다. 프레임 애니메이션이나 SVGA와 같은 애니메이션 솔루션에서는 리소스를 요청하기 위해 매번 사진을 사용하지 않습니다.🎜🎜아틀라스로 패키징하는 경우가 더 많으며, 아틀라스 패키징 도구인 texturepacker가 더욱 인기가 있습니다. .🎜🎜두 번째로, 게임 장면이 너무 많고 일반적으로 리소스를 단계별로 로드해야 합니다. 때로는 애니메이션 모델에 적게는 12장, 많게는 100장의 사진이 포함됩니다. 🎜🎜🎜사진 사용. 🎜🎜🎜작성 방법을 살펴보겠습니다. 아틀라스 패키징 도구입니다.🎜

도구 디자인" >아틀라스를 사용해야 하는 이유

웹 개발

🎜웹 개발에서는 브라우저에 그림이 표시될 때마다 요청해야 합니다. 서버 리소스입니다.🎜🎜예를 들어 🎜3 4k🎜의 각 요청과 🎜12k의 한 요청🎜 사이에는 근본적인 차이가 있으며, 대부분의 경우 하나의 요청은 🎜3 * 4k🎜가 아닙니다.🎜🎜아틀라스 사용 리소스 로딩을 최적화하고 웹사이트 성능을 향상할 수 있습니다. 🎜

게임 개발

🎜게임 개발에서는 일반적으로 아틀라스를 사용하는 것이 중요합니다. 프레임 애니메이션이나 SVGA와 같은 애니메이션 솔루션에서는 리소스를 요청하기 위해 매번 사진을 사용하지 않습니다.🎜🎜아틀라스로 패키징하는 경우가 더 많으며, 아틀라스 패키징 도구인 texturepacker가 더욱 인기가 있습니다. .🎜🎜두 번째로, 게임 장면이 너무 많고 일반적으로 리소스를 단계별로 로드해야 합니다. 때로는 애니메이션 모델에 적게는 12장, 많게는 100장의 사진이 포함됩니다. 🎜🎜🎜사진 사용. 🎜🎜🎜작성 방법을 살펴보겠습니다. 아틀라스 패키징 도구입니다.🎜

도구 디자인

시작 스크립트 작성
스크립트 IO
Traverse 노드 트리를 생성하기 위한 파일
새 아틀라스 위치 정보 가져오기
图集打包并输出
如何使用
展望
나중 텍스트
웹 프론트엔드 JS 튜토리얼 노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

Nov 29, 2021 pm 06:53 PM
node

이 글은 node를 사용하여 앨범 패키징 도구를 작성하는 방법을 단계별로 설명합니다. 이 글이 모든 사람에게 도움이 되기를 바랍니다.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

우연히 매우 유용한 크로스 플랫폼 이미지 인코딩 및 디코딩 라이브러리인 node-images를 발견했습니다.

API를 주의 깊게 읽은 후 이를 사용하여 elf 아틀라스를 만드는 아이디어를 생각해 냈습니다. .

그래서 이 도구 sprites-pack-tool이 탄생했습니다.sprites-pack-tool.

你可以在github查看

https://github.com/xdq1553/MySpritesPackTool

你可以使用npm安装

https://www.npmjs.com/package/sprites-pack-tool


对于精灵图集, 我想大家都不陌生.

比如把下面的几张图片合成一张.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

这一张图集就是我用本文介绍的工具打包合成的.

合成的图片品质依然十分高呢.

为什么需要使用图集

web开发

我们在web开发中, 每次在浏览器展示一张图片都需要请求一次服务器资源.

举个例子, 3次请求每次4k, 和一次请求12k还是有本质区别的, 然后更多的时候一次请求并不是3 * 4k.

使用图集能让我们优化资源加载, 提高网站的性能.

游戏开发

在游戏开发中, 图集的使用至关重要, 不管是一般帧动画还是svga等动画解决方案, 都不会每张图片去请求资源.

更多的时候, 我们都是打包成图集, 而图集打包工具texturepacker更是大行其道.

其次, 游戏场景过多, 我们一般都需要分步加载资源, 有的时候一个动画模型, 涉及的图片少则十来张, 多则近百张.

图集的使用不可或缺.

下面我们就来看下如何编写一款图集打包工具.

工具设计

开发一个图集打包工具脚本需要什么技能.

  • node.js编程能力

  • 二维矩形装箱算法

然后我们思考如何去打包一张图集.

  • 我们需要找到需要打包的文件夹, 可能有多个或者嵌套文件夹.

  • 图集是多张散图拼合而成.

  • 图集的大小需要可配置

  • 尽可能的压缩图集空间, 使每张图紧密贴合

  • 每个文件夹打包成一个图集, 需要考虑图片过多的情况

  • 可能需要生成图集所需要的json文件, 记录图片位置信息

开始编写脚本

脚本IO

我这里是这样设计.

首先我们需要一个打包对象实例MySpritePackTool, 同时支持写入配置参数options.

/** 图集打包对象 */
const MySpritePackTool = function (opt) {
    this.options = {
        //一个文件夹图片过多或者过长 递归最大次数
        maxCount: opt.maxCount || 2,
        //需要打包图集的文件路径
        assetsPath: opt.assetsPath,
        //输出文件路径
        outPutPath: opt.outPutPath,
        //一张图集打包最大size
        maxSize: { width: 2048, height: 2048 }
    }
};
로그인 후 복사

然后我们需要输出这个对象, 可以被其他项目所引用.

module.exports = MySpritePackTool;
로그인 후 복사

遍历文件生成节点树

我们的输入参数尽可能的少, 这样就需要我们程序去遍历文件夹.

例如, 我们有如下的目录树:

|--assets
   |--index
      |--img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.
      |--img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.
   |--login
      |--img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.
   |--img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.
   |--img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.
로그인 후 복사

我们需要每个文件夹下打包出一张图集.

思考: 需要什么样的数据结构?

首先便于js解析, 我们约定一个对象,

每一层, 需要一个图片信息容器assets;

一个所包含的图片标识keys;

一个文件夹名字, 也方便我们后面为图集命名name;

然后每层文件夹前套相同对象;

结构如下:

{
  assets: [
    {
      id: 'assets/img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.',
      width: 190,
      height: 187
    },
    ...
  ],
  name: 'assets',
  keys: 'img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.,img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.,',
  index: {
    assets: [
        {
            id: 'assets/index/img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.',
            width: 190,
            height: 187
        },
        ...
    ],
    name: 'index',
    keys: 'img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.,img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.,'
  },
  login: {
    assets: [
        {
            id: 'assets/login/img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.',
            width: 190,
            height: 187
        }
    ],
    name: 'index',
    keys: 'img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.,'
  },
}
로그인 후 복사

不难发现, 我们已经可以得到需要打包的所有文件和文件夹.

那么用程序如何实现呢?

主要用到nodejs的fs模块来递归操作文件夹, 并输出所需要的节点树.

注意在书写的时候需要判断是图片还是文件夹.

MySpritePackTool.prototype.findAllFiles = function (obj, rootPath) {
    let nodeFiles = [];
    if (fs.existsSync(rootPath)) {
        //获取所有文件名
        nodeFiles = fs.readdirSync(rootPath);

        //组装对象
        let nameArr = rootPath.split('/');
        obj["assets"] = [];
        obj["name"] = nameArr[nameArr.length - 1];
        obj["keys"] = "";

        nodeFiles.forEach(item => {
            //判断不是图片路径
            if (!/(.png)|(.jpe?g)$/.test(item)) {
                let newPath = path.join(rootPath, item);
                //判断存在文件 同时是文件夹系统
                if (fs.existsSync(newPath) && fs.statSync(newPath).isDirectory()) {
                    // console.log("获得新的地址", newPath);
                    obj[item] = {};
                    this.findAllFiles(obj[item], newPath);

                } else {
                    console.log(`文件路径: ${newPath}不存在!`);
                }

            } else {
                console.log(`图片路径: ${item}`);
                obj["keys"] += item + ",";
                let params = {};
                params["id"] = path.resolve(rootPath, `./${item}`);
                //获得图片宽高
                params["width"] = images(path.resolve(rootPath, `./${item}`)).width();
                params["height"] = images(path.resolve(rootPath, `./${item}`)).height();
                obj["assets"].push(params);
            }
        })

    } else {
        console.log(`文件路径: ${rootPath}不存在!`);
    }
}
로그인 후 복사

这样子我们就可以得到我们所需要的节点树了.

获取新的图集位置信息

我们对文件夹的操作已经完成, 这时候我们就需要思考.

如何把这些零散的图片打包到一张图片上.

散图有两个信息, 一个width和一个height

github에서 볼 수 있습니다🎜🎜https://github.com/xdq1553/MySpritesPackTool🎜🎜볼 수 있습니다 npm을 사용하여 설치🎜🎜 https://www.npmjs.com/package/sprites-pack-tool🎜

🎜모두가 🎜Sprite Atlas🎜에 익숙하다고 생각합니다.🎜🎜🎜예를 들어 , 다음 사진을 찍으세요. 사진이 하나로 결합됩니다.🎜🎜🎜노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다. 🎜🎜노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다. 🎜🎜이 아틀라스는 이 글에서 소개한 도구를 사용하여 제가 직접 패키징하고 합성한 것입니다. 🎜🎜합성된 사진의 품질은 여전히 ​​매우 높습니다. 🎜

아틀라스를 사용해야 하는 이유

웹 개발

🎜웹 개발에서는 브라우저에 그림이 표시될 때마다 요청해야 합니다. 서버 리소스입니다.🎜🎜예를 들어 🎜3 4k🎜의 각 요청과 🎜12k의 한 요청🎜 사이에는 근본적인 차이가 있으며, 대부분의 경우 하나의 요청은 🎜3 * 4k🎜가 아닙니다.🎜🎜아틀라스 사용 리소스 로딩을 최적화하고 웹사이트 성능을 향상할 수 있습니다. 🎜

게임 개발

🎜게임 개발에서는 일반적으로 아틀라스를 사용하는 것이 중요합니다. 프레임 애니메이션이나 SVGA와 같은 애니메이션 솔루션에서는 리소스를 요청하기 위해 매번 사진을 사용하지 않습니다.🎜🎜아틀라스로 패키징하는 경우가 더 많으며, 아틀라스 패키징 도구인 texturepacker가 더욱 인기가 있습니다. .🎜🎜두 번째로, 게임 장면이 너무 많고 일반적으로 리소스를 단계별로 로드해야 합니다. 때로는 애니메이션 모델에 적게는 12장, 많게는 100장의 사진이 포함됩니다. 🎜🎜🎜사진 사용. 🎜🎜🎜작성 방법을 살펴보겠습니다. 아틀라스 패키징 도구입니다.🎜

도구 디자인

🎜아틀라스 패키징을 개발하려면 어떤 기술이 필요한가요? 도구 스크립트.🎜
  • 🎜🎜node.js🎜프로그래밍 능력🎜
  • 🎜2차원 직사각형 비닝 알고리즘🎜
🎜그런 다음 아틀라스를 패키징하는 방법에 대해 생각해 보겠습니다.🎜
  • 🎜패키징해야 할 폴더를 찾아야 합니다. 여러 개 또는 중첩된 폴더.🎜
  • 🎜사진 세트는 여러 개의 흩어져 있는 그림으로 구성됩니다. 🎜
  • 🎜아틀라스의 크기를 구성할 수 있어야 합니다🎜
  • 🎜각 사진이 빽빽하게 들어가도록 아틀라스의 공간을 최대한 압축하세요 🎜
  • 🎜각 폴더는 하나의 아틀라스로 포장되어 있습니다. 사진이 너무 많으면 상황을 고려하셔야 합니다. /li>
  • 🎜아틀라스에 필요한 json 파일을 생성하고 사진의 위치 정보를 기록해야 할 수도 있습니다. 🎜

시작 스크립트 작성

스크립트 IO

🎜저는 이렇게 설계되었습니다.🎜🎜먼저 패키징 개체 인스턴스 MySpritePackTool가 필요합니다. 구성 매개변수 옵션 작성도 지원합니다.🎜
/** 
 * 确定宽高 w h
 * 空白区域先放一个, 剩下的寻找右边和下边
 * 是否有满足右边的, 有则 放入 无则 继续遍历
 * 是否有满足下边的, 有则 放入 无则 继续遍历
 */
const Packer = function (w, h) {
    this.root = { x: 0, y: 0, width: w, height: h };
    // /** 匹配所有的方格 */
    Packer.prototype.fit = function (blocks) {

        let node;
        for (let i = 0; i < blocks.length; i++) {
            let block = blocks[i];
            node = this.findNode(this.root, block.width, block.height);
            if (node) {
                let fit = this.findEmptyNode(node, block.width, block.height);
                block.x = fit.x;
                block.y = fit.y;
                block.fit = fit;
            }
        }

    }

    /** 找到可以放入的节点 */
    Packer.prototype.findNode = function (node, w, h) {
        if (node.used) {
            return this.findNode(node.rightArea, w, h) || this.findNode(node.downArea, w, h);
        } else if (node.width >= w && node.height >= h) {
            return node;
        } else {
            return null;
        }
    }

    /** 找到空位 */
    Packer.prototype.findEmptyNode = function (node, w, h) {
        //已经使用过的 删除 
        node.used = true;
        //右边空间
        node.rightArea = {
            x: node.x + w,
            y: node.y,
            width: node.width - w,
            height: h
        };

        //下方空位
        node.downArea = {
            x: node.x,
            y: node.y + h,
            width: node.width,
            height: node.height - h
        }
        return node;
    }
}
로그인 후 복사
로그인 후 복사
🎜그런 다음 다른 프로젝트에서 사용할 수 있는 이 개체를 출력해야 합니다.🎜
//记录使用的总的区域
this.usedArea = { width: 0, height: 0 };
//记录未被装入的矩形
this.levelBlocks = [];
로그인 후 복사
로그인 후 복사

Traverse 노드 트리를 생성하기 위한 파일

🎜입력 매개변수가 가능한 적으므로 폴더를 탐색하려면 프로그램이 필요합니다.🎜🎜예를 들어 다음과 같은 디렉토리 트리가 있습니다.🎜
`${obj[&#39;name&#39;] + (count ? "-" + count : &#39;&#39;)}`
로그인 후 복사
로그인 후 복사
🎜아틀라스를 패키징해야 합니다. 🎜🎜🎜생각하기: 어떤 종류의 데이터 구조가 필요한가?🎜🎜🎜우선 js 파싱에 편리하고 객체에 동의합니다.🎜 🎜각 레이어에는 이미지 정보 컨테이너 <코드>자산이 필요합니다 ; 🎜🎜포함된 이미지 식별자 keys 🎜🎜나중에 앨범을 만들 때에도 편리한 폴더 이름 이름 name;🎜🎜그런 다음 각 폴더 레이어 앞에 동일한 개체를 배치합니다.🎜🎜🎜구조는 다음과 같습니다.🎜🎜
MySpritePackTool.prototype.dealImgsPacking = function (obj) {
    let count = 0;
    if (obj.hasOwnProperty("assets")) {
        let newBlocks = obj["assets"];
        obj["assets"] = [];

        while (newBlocks.length > 0 && count < this.options.maxCount) {
            let packer1 = new Packer(this.options.maxSize.width, this.options.maxSize.height);
            packer1.fit(newBlocks);

            let sheets1 = {
                maxArea: packer1.usedArea,
                atlas: newBlocks,
                fileName: `${obj[&#39;name&#39;] + (count ? "-" + count : &#39;&#39;)}`
            };
            newBlocks = packer1.levelBlocks;
            obj["assets"].push(sheets1);
            count++;
        }
    }
    for (let item in obj) {
        if (obj[item].hasOwnProperty("assets")) {
            this.dealImgsPacking(obj[item]);
        }
    }
}
로그인 후 복사
로그인 후 복사
🎜패키징해야 하는 모든 파일과 폴더를 이미 얻을 수 있다는 것을 찾는 것은 어렵지 않습니다.🎜 🎜🎜 그럼 어떻게 프로그램으로 구현할까요?🎜🎜🎜주로 nodejs의 🎜fs 모듈🎜을 사용하여 폴더를 재귀적으로 동작시켜 필요한 노드 트리를 출력합니다.🎜🎜주의할 점은 작업할 때 사진인지 폴더인지 판단해야 한다는 점입니다. 🎜
  assets: [
    { 
        maxArea: { width: 180,height: 340 }, 
        atlas: [
            {
                id: &#39;assets/index/img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.&#39;,
                width: 190,
                height: 187,
                x: 0,
                y: 0
            }
        ], 
        fileName: &#39;assets&#39; },
        ...
  ]
로그인 후 복사
로그인 후 복사
🎜이 방법으로 필요한 노드 트리를 얻을 수 있습니다.🎜

새 아틀라스 위치 정보 가져오기

🎜폴더에 대한 작업이 완료되었습니다. 이번에는 생각해볼 필요가 있습니다.🎜🎜흩어진 사진을 어떻게 하나의 사진으로 묶을 수 있는지.🎜🎜흩어진 사진에는 너비높이 두 가지 정보가 있는데, 실제로는 직사각형입니다.🎜

我们现在所要做的就是把这些不同面积的矩形放到一个具有最大长宽的大矩形中.


跳开图片, 从矩形放置入手

二维矩形装箱算法有不少, 我这里选用一种比较简单的.

首先得到一个具有最大长宽的矩形盒子.

我们先放入一个矩形A, 这样子, 剩余区域就有两块: 矩形A的右边矩形A的下边.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

然后我们继续放入矩形B, 可以先右再下, 然后基于矩形B又有两块空白空间.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

依次类推, 我们就可以将合适的矩形全部放入.

举个例子

把左边的散装矩形放入右边的矩形框中, 可以得到:

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

可以看到, 我们节省了很多空间, 矩形排列紧凑.

如果用代码实现, 是怎么样的呢?

/** 
 * 确定宽高 w h
 * 空白区域先放一个, 剩下的寻找右边和下边
 * 是否有满足右边的, 有则 放入 无则 继续遍历
 * 是否有满足下边的, 有则 放入 无则 继续遍历
 */
const Packer = function (w, h) {
    this.root = { x: 0, y: 0, width: w, height: h };
    // /** 匹配所有的方格 */
    Packer.prototype.fit = function (blocks) {

        let node;
        for (let i = 0; i < blocks.length; i++) {
            let block = blocks[i];
            node = this.findNode(this.root, block.width, block.height);
            if (node) {
                let fit = this.findEmptyNode(node, block.width, block.height);
                block.x = fit.x;
                block.y = fit.y;
                block.fit = fit;
            }
        }

    }

    /** 找到可以放入的节点 */
    Packer.prototype.findNode = function (node, w, h) {
        if (node.used) {
            return this.findNode(node.rightArea, w, h) || this.findNode(node.downArea, w, h);
        } else if (node.width >= w && node.height >= h) {
            return node;
        } else {
            return null;
        }
    }

    /** 找到空位 */
    Packer.prototype.findEmptyNode = function (node, w, h) {
        //已经使用过的 删除 
        node.used = true;
        //右边空间
        node.rightArea = {
            x: node.x + w,
            y: node.y,
            width: node.width - w,
            height: h
        };

        //下方空位
        node.downArea = {
            x: node.x,
            y: node.y + h,
            width: node.width,
            height: node.height - h
        }
        return node;
    }
}
로그인 후 복사
로그인 후 복사

使用递归, 代码量很少, 但是功能强大.

但是有一个问题, 如果超出定长定宽, 或者一个矩形装不完, 我们的算法是不会放入到大矩形中的.

这样子就有点不满足我们的图集打包思路了.

所以我们还需要将这个算法改进一下;

加入两个变量, 一个记录使用的总的区域, 一个记录未被装入的矩形.

//记录使用的总的区域
this.usedArea = { width: 0, height: 0 };
//记录未被装入的矩形
this.levelBlocks = [];
로그인 후 복사
로그인 후 복사

详细代码可以查看源码中的packing.

当然, 这里只是最简单的一种二维装箱算法

还有一种加强版的装箱算法, 我放在源码里了, 这里就不赘述了, 原理基本一致

现在, 我们已经可以将矩形合适的装箱了, 那怎么使用去处理成图集呢?

定义一个dealImgsPacking方法, 继续去处理我们的节点树.

这里用到了我们的配置项maxCount, 就是为了一张图集装不完, 多打出几张图集的作用.

然后我们打包出来的图集命名使用文件夹 + 当前是第几张的形式.

`${obj[&#39;name&#39;] + (count ? "-" + count : &#39;&#39;)}`
로그인 후 복사
로그인 후 복사

具体方法如下:

MySpritePackTool.prototype.dealImgsPacking = function (obj) {
    let count = 0;
    if (obj.hasOwnProperty("assets")) {
        let newBlocks = obj["assets"];
        obj["assets"] = [];

        while (newBlocks.length > 0 && count < this.options.maxCount) {
            let packer1 = new Packer(this.options.maxSize.width, this.options.maxSize.height);
            packer1.fit(newBlocks);

            let sheets1 = {
                maxArea: packer1.usedArea,
                atlas: newBlocks,
                fileName: `${obj[&#39;name&#39;] + (count ? "-" + count : &#39;&#39;)}`
            };
            newBlocks = packer1.levelBlocks;
            obj["assets"].push(sheets1);
            count++;
        }
    }
    for (let item in obj) {
        if (obj[item].hasOwnProperty("assets")) {
            this.dealImgsPacking(obj[item]);
        }
    }
}
로그인 후 복사
로그인 후 복사

通过这个方法我们改造了之前的节点树;

将之前节点树中的assest变为了一个数组, 每个数组元素代表一张图集信息.

结构如下:

  assets: [
    { 
        maxArea: { width: 180,height: 340 }, 
        atlas: [
            {
                id: &#39;assets/index/img-노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.&#39;,
                width: 190,
                height: 187,
                x: 0,
                y: 0
            }
        ], 
        fileName: &#39;assets&#39; },
        ...
  ]
로그인 후 복사
로그인 후 복사

我们可以清晰的得到, 打包之后的图集, 最大宽高是maxArea, 每张图宽高位置信息是atlas,以及图集名称fileName.

接下来, 就是最后一步了, 绘制新的图片, 并输出图片文件.

注意
我们在使用打包算法的时候, 可以先进行一下基于图片大小的排序
这样以来打包出来的图集会留白更小

图集打包并输出

这里图集的绘制和输出均是使用了node-images的API;

遍历之前得到的节点树, 首先绘制一张maxArea大小的空白图像.

images(item["maxArea"].width, item["maxArea"].height)
로그인 후 복사

然后遍历一张图集所需要的图片信息, 将每一张图片绘制到空白图像上.

//绘制空白图像
let newSprites = images(item["maxArea"].width, item["maxArea"].height);
//绘制图集
imgObj.forEach(it => {
    newSprites.draw(images(it["id"]), it["x"], it["y"]);
});
로그인 후 복사

然后绘制完一张图集输出一张.

newSprites.save(`${this.options.outPutPath}/${item[&#39;fileName&#39;]}.png`);
로그인 후 복사

最后对节点树递归调用, 绘制出所有的图集.

具体代码如下:

MySpritePackTool.prototype.drawImages = function (obj) {
    let count = 0;
    if (obj.hasOwnProperty("assets")) {
        //打包出一个或者多个图集
        let imgsInfo = obj["assets"];
        imgsInfo.forEach(item => {
            if (item.hasOwnProperty("atlas")) {
                let imgObj = item["atlas"];
                // console.log("8888",imgObj)
                //绘制一张透明图像
                let newSprites = images(item["maxArea"].width, item["maxArea"].height);
                imgObj.forEach(it => {
                    newSprites.draw(images(it["id"]), it["x"], it["y"]);
                });

                newSprites.save(`${this.options.outPutPath}/${item[&#39;fileName&#39;]}.png`);
                count++;
            }
        })
    }

    for (let item in obj) {
        if (obj[item].hasOwnProperty("assets")) {
            this.drawImages(obj[item]);
        }
    }

}
로그인 후 복사

这样子, 我们就大功告成了,

运行测试一下, 可以得到如下的图集:

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.

效果还不错.

如何使用

安装

npm i sprites-pack-tool
로그인 후 복사

使用

const MySpritePackTool = require("sprites-pack-tool");
const path = require("path");
/** 打包最多递归次数 */
const MAX_COUNT = 2;
//需要合成的图集的路径
const assetsPath = path.resolve(__dirname, "./assets");

/** 图集打包工具配置*/
const mySpritePackTool = new MySpritePackTool({
    //一个文件夹图片过多或者过长 递归最大次数
    maxCount: MAX_COUNT,
    //需要打包图集的文件路径
    assetsPath: assetsPath,
    //输出文件路径
    outPutPath: path.resolve(__dirname, "./res"),
    //一张图集打包最大size
    maxSize: { width: 2048,height: 2048}
});
/** 图集打包 */
mySpritePackTool.Pack2Sprite();
로그인 후 복사

展望

当然, 这个工具只是初版, 后续还会继续优化并增加新的功能.

  • 算法可以继续优化, 现在留白也挺多.

  • 文件夹操作,可以优化. 比如写入图片可以每个文件夹下一张图集.

  • 增加更多配置项, 比如开启图片压缩

  • 增加json文件

  • ...

我大致看了下, 市场上有几款图集打包工具, 要么基于texturePacker, 要么基于imagemagick;

使用这俩应用开放的API也是可以打包图集的, 效果品质可能更好.

但是你还得额外安装一个应用.

同样的, 你也可以使用webpack的一些loader或者plugins. 目的都是打包图集.

이 글에서 소개하는 도구들은 상대적으로 가볍지만 한 번만 사용하면 바로 사용할 수 있습니다.

나중 텍스트

한동안 글을 쓰지 않았는데 우연히 그런 글을 쓰고 싶었습니다. 이번 주말에 도구로 만들어서 실행해봤는데 결과는 나쁘지 않네요

더 좋은 방법이 있으면 댓글 남겨주시면 정말 감사하겠습니다~

누구나 댓글과 수정 환영합니다. 작가님의 실력이 아직 얕아서 부적절한 부분이 있으면 지적해주세요

소스코드

github에서 보실 수 있습니다: https://github.com/xdq1553/MySpritesPackTool

npm을 사용하실 수 있습니다 설치하려면: https://www.npmjs.com/package/sprites-pack-tool

Reference

node-images: https://github.com/zhangyuanwei/node-images

spritesheet: https: //github.com/krzysztof-o/spritesheet.js

이 기사는 피상적입니다. 여러분 모두 주저하지 말고 댓글과 좋아요를 남겨주세요~

원본 주소: https://juejin.cn /post/7035809483666227230

저자: 어린 시절부터 곰이었습니다

노드 관련 지식을 더 보려면 nodejs 튜토리얼 을 방문하세요! !

위 내용은 노드를 사용하여 아틀라스 패키징 도구를 개발하는 방법을 단계별로 안내합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

nvm에서 노드를 삭제하는 방법 nvm에서 노드를 삭제하는 방법 Dec 29, 2022 am 10:07 AM

nvm을 사용하여 노드를 삭제하는 방법: 1. "nvm-setup.zip"을 다운로드하여 C 드라이브에 설치합니다. 2. "nvm -v" 명령을 통해 환경 변수를 구성하고 버전 번호를 확인합니다. install" 명령 노드 설치; 4. "nvm uninstall" 명령을 통해 설치된 노드를 삭제합니다.

Express를 사용하여 노드 프로젝트에서 파일 업로드를 처리하는 방법 Express를 사용하여 노드 프로젝트에서 파일 업로드를 처리하는 방법 Mar 28, 2023 pm 07:28 PM

파일 업로드를 처리하는 방법은 무엇입니까? 다음 글에서는 Express를 사용하여 노드 프로젝트에서 파일 업로드를 처리하는 방법을 소개하겠습니다. 도움이 되길 바랍니다.

Node 서비스의 Docker 미러링을 수행하는 방법은 무엇입니까? 극한 최적화에 대한 자세한 설명 Node 서비스의 Docker 미러링을 수행하는 방법은 무엇입니까? 극한 최적화에 대한 자세한 설명 Oct 19, 2022 pm 07:38 PM

이 기간 동안 저는 Tencent 문서의 모든 카테고리에 공통되는 HTML 동적 서비스를 개발 중입니다. 다양한 카테고리에 대한 액세스 생성 및 배포를 촉진하고 클라우드로 이동하는 추세에 부응하기 위해. Docker를 사용하여 서비스 콘텐츠를 수정하고 제품 버전을 균일하게 관리합니다. 이 글에서는 제가 Docker를 서비스하면서 쌓은 최적화 경험을 여러분의 참고용으로 공유하겠습니다.

Node의 프로세스 관리 도구 'pm2”에 대한 심층 분석 Node의 프로세스 관리 도구 'pm2”에 대한 심층 분석 Apr 03, 2023 pm 06:02 PM

이 기사에서는 Node의 프로세스 관리 도구인 "pm2"를 공유하고 pm2가 필요한 이유, pm2 설치 및 사용 방법에 대해 설명합니다. 모두에게 도움이 되기를 바랍니다!

PI 노드 교육 : PI 노드 란 무엇입니까? Pi 노드를 설치하고 설정하는 방법은 무엇입니까? PI 노드 교육 : PI 노드 란 무엇입니까? Pi 노드를 설치하고 설정하는 방법은 무엇입니까? Mar 05, 2025 pm 05:57 PM

Pinetwork 노드에 대한 자세한 설명 및 설치 안내서이 기사에서는 Pinetwork Ecosystem을 자세히 소개합니다. Pi 노드, Pinetwork 생태계의 주요 역할을 수행하고 설치 및 구성을위한 전체 단계를 제공합니다. Pinetwork 블록 체인 테스트 네트워크가 출시 된 후, PI 노드는 다가오는 주요 네트워크 릴리스를 준비하여 테스트에 적극적으로 참여하는 많은 개척자들의 중요한 부분이되었습니다. 아직 Pinetwork를 모른다면 Picoin이 무엇인지 참조하십시오. 리스팅 가격은 얼마입니까? PI 사용, 광업 및 보안 분석. Pinetwork 란 무엇입니까? Pinetwork 프로젝트는 2019 년에 시작되었으며 독점적 인 Cryptocurrency Pi Coin을 소유하고 있습니다. 이 프로젝트는 모든 사람이 참여할 수있는 사람을 만드는 것을 목표로합니다.

pkg를 사용하여 Node.js 프로젝트를 실행 파일로 패키징하는 방법에 대해 이야기해 보겠습니다. pkg를 사용하여 Node.js 프로젝트를 실행 파일로 패키징하는 방법에 대해 이야기해 보겠습니다. Dec 02, 2022 pm 09:06 PM

nodejs 실행 파일을 pkg로 패키징하는 방법은 무엇입니까? 다음 기사에서는 pkg를 사용하여 Node 프로젝트를 실행 파일로 패키징하는 방법을 소개합니다. 도움이 되기를 바랍니다.

npm node gyp가 실패하는 경우 수행할 작업 npm node gyp가 실패하는 경우 수행할 작업 Dec 29, 2022 pm 02:42 PM

"node-gyp.js"와 "Node.js"의 버전이 일치하지 않아 npm node gyp가 실패했습니다. 해결 방법: 1. "npm 캐시 clean -f"를 통해 노드 캐시를 지웁니다. 2. "npm install - g n" n 모듈을 설치합니다. 3. "n v12.21.0" 명령을 통해 "node v12.21.0" 버전을 설치합니다.

싱글 사인온(SSO) 시스템이란 무엇입니까? nodejs를 사용하여 구현하는 방법은 무엇입니까? 싱글 사인온(SSO) 시스템이란 무엇입니까? nodejs를 사용하여 구현하는 방법은 무엇입니까? Feb 24, 2023 pm 07:33 PM

싱글 사인온(SSO) 시스템이란 무엇입니까? nodejs를 사용하여 구현하는 방법은 무엇입니까? 다음 글에서는 Node를 사용하여 Single Sign-On 시스템을 구현하는 방법을 소개하겠습니다. 도움이 되길 바랍니다.

See all articles