如何在精灵中缩小矩形以排除透明像素



我有一个包含透明像素包围的不透明对象的Sprite。我还有一个Rectangle,它代表了我想用BitmapData.draw()渲染的Sprite的一部分。

问题是我得到的Rectangle也含有透明的部分。我如何缩小Rectangle只包括不透明的部分,而忽略透明的环境?

kapep的答案正是我想做的,但问题是源是Sprite,而不是BitmapData对象,并且我在Sprite上没有getColorBoundsRect()

您可以使用getColorBoundsRect

var mask:uint = 0xFF000000; // ignore rgb, use alpha only
var transparent = 0x00000000; 
var rect:Rectangle = imageBitmapData.getColorBoundsRect(mask, transparent, false);

要操作精灵的像素,首先需要将其绘制到BitmapData(使用BitmapData.draw)。然后在用getColorBoundsRect获得一个较小的矩形后,用该矩形的尺寸创建一个新的BitmapData。最后一步是使用copyPixels,将矩形的面积从第一张图像复制到新图像。

var imageBitmapData:BitmapData = new BitmapData(image.width, image.height, true, 0);
imageBitmapData.draw(image);
// var rect =  ... as above
var resultBitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0);
resultBitmapData.copyPixels(imageBitmapData, rect, new Point(0,0));

我发现你的问题有点令人困惑,但如果我理解正确,以下是你应该做的:

首先,使用BitmapData.draw()拍摄雪碧的"图片",将其放置在新的BitmapData实例中。然后,你需要找到透明区域的边界。对每条边分别执行此操作。从每个边缘开始,以固定的间隔(例如每10个像素)观察像素,看看它们是否都是透明的。如果是,向中心移动一定数量的像素,然后重复。下面是一些示例代码(未测试!):

// Bitmap data already exists
var bmd:BitmapData; // content already exists
var isTransparent:Function = function(bmd:BitmapData, x:uint, y:uint):Boolean
{
    var pixelValue:uint = bmd.getPixel32(0, 0);
    var alphaValue:uint = pixelValue >> 24 & 0xFF;
    return (alphaValue == 0);
};
// Look at right edge
var curX:uint = bmd.width-1;
var interval:uint = 10;
var iterations:uint = Math.ceil(bmd.height / interval);
var transparentX:uint = curX + 1;
var stillTransparent:Boolean = true;
while (stillTransparent)
{
   for (var i:uint=0; i<iterations; i++)
   {
      var curY:int = i * interval;
      if (!isTransparent(bmd, curX, curY))
      {
         stillTransparent = false;
         break;
      }
   }
   // If stillTransparent==true, this entire column was transparent.
   // Get ready for next loop by moving in [interval] pixels
   if (stillTransparent)
   {
      transparentX = curX
      curX -= interval; // check needed if may be completely transparent
   }   
}
// transparentX now represents the last known x value on 
// the right edge where everything was still transparent.

最后,将透明度边界测试的xy结果用于创建Rectangle,并使用BitmapData.draw仅将相关的非透明部分复制到新的BitmapData实例中。

最新更新