Sprite Sheet自动检测单个Sprite边界 [英] Sprite Sheet Detect Individual Sprite Bounds Automatically

查看:105
本文介绍了Sprite Sheet自动检测单个Sprite边界的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出如下的精灵表:

我想编写一种算法,该算法可以循环遍历像素数据并确定每个谨慎的sprite的边界矩形.

如果我们假设对于每个像素X,Y,我可以拉为true(像素不完全透明)或false(像素完全透明),那么我将如何自动为每个sprite生成边界矩形? /p>

结果数据应为具有{x,y,width,height}的矩形对象数组.

这是同一张图片,但前四个精灵的边界标记为浅蓝色:

任何人都可以逐步介绍如何如上所述检测这些界限吗?

解决方案

这个怎么样?唯一的缺点是您需要图像的可写版本来标记访问过的像素,否则泛滥将永远不会终止.

Process each* scan line in turn
  For each scanline, walk from left to right, until you find a non-transparent pixel P.
    If the location of P is already inside a known bounded box
      Continue to the right of the bounded box
    Else
      BBox = ExploreBoundedBox(P)
      Add BBox to the collection of known bounded boxes

Function ExploreBoundedBox(pStart)
  Q = new Queue(pStart)
  B = new BoundingBox(pStart)

  While Q is not empty
    Dequeue the front element as P
    Expand B to include P

    For each of the four neighbouring pixels N
      If N is not transparent and N is not marked
        Mark N
        Enqueue N at the back of Q

  return B

您不需要处理每条扫描线,您可以每10条或每30条扫描线进行一次处理.只要不超过最小精灵高度即可.

Given a sprite sheet like this:

I would like to write an algorithm that can loop through the pixel data and determine the bounding rectangle of each discreet sprite.

If we assume that for each pixel X, Y that I can pull either true (pixel is not totally transparent) or false (pixel is totally transparent), how would I go about automatically generating the bounding rectangles for each sprite?

The resulting data should be an array of rectangle objects with {x, y, width, height}.

Here's the same image but with the bounds of the first four sprites marked in light blue:

Can anyone give a step-by-step on how to detect these bounds as described above?

解决方案

How about this? The only downside is that you'll need a writable version of your image to mark visited pixels in, or the floodfill will never terminate.

Process each* scan line in turn
  For each scanline, walk from left to right, until you find a non-transparent pixel P.
    If the location of P is already inside a known bounded box
      Continue to the right of the bounded box
    Else
      BBox = ExploreBoundedBox(P)
      Add BBox to the collection of known bounded boxes

Function ExploreBoundedBox(pStart)
  Q = new Queue(pStart)
  B = new BoundingBox(pStart)

  While Q is not empty
    Dequeue the front element as P
    Expand B to include P

    For each of the four neighbouring pixels N
      If N is not transparent and N is not marked
        Mark N
        Enqueue N at the back of Q

  return B

You don't need to process every scanline, you could do every 10th, or every 30th scanline. As long as it doesn't exceed the minimum sprite height.

这篇关于Sprite Sheet自动检测单个Sprite边界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆