如何缩小Sprite中的Rectangle以排除透明像素?

时间:2011-10-02 22:11:28

标签: flash actionscript-3 actionscript

我有一个Sprite,其中包含由透明像素包围的不透明对象。我还有一个Rectangle代表我要使用Sprite呈现的BitmapData.draw()的一部分。

问题是我获得的Rectangle还包含透明部分。如何缩小Rectangle以仅包含不透明部分并忽略透明环境?

kapep的回答正是我想要做的,但问题是来源是Sprite,而不是BitmapData对象,我没有getColorBoundsRect() Sprite

2 个答案:

答案 0 :(得分:3)

您可以使用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));

答案 1 :(得分:0)

我发现你的问题有点混乱,但如果我理解正确,这就是你应该做的:

首先,使用BitmapData.draw()获取Sprite的“图片”,将其放入新的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实例。