AS3如何检查BitmapData是否为空
我有一个代码可以删除蒙版影片剪辑。 (学分此处) 我想知道如何检查整个影片剪辑是否已被删除。 所以我想我必须检查 BitmapData 是否为空,但我可能大错特错了! 如何检查影片剪辑的每个像素是否已被删除?
当然我下面的例子是错误的,但我认为它必须是这样的。
if (erasableBitmapData = empty)
{
trace("empty")
}
var lineSize:Number=40;
var doDraw:Boolean=false;
var resumeDrawing:Boolean=false;
var erasableBitmapData:BitmapData = new BitmapData(700, 500, true, 0xFFFFFFFF);
var erasableBitmap:Bitmap = new Bitmap(erasableBitmapData);
erasableBitmap.cacheAsBitmap = true;
addChild(erasableBitmap);
maskee.cacheAsBitmap = true;
maskee.mask = erasableBitmap;
var eraserClip:Sprite = new Sprite();
initEraser();
function initEraser():void {
eraserClip.graphics.lineStyle(lineSize,0xff0000);
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
var drawnBitmapData:BitmapData = new BitmapData(700, 500, true, 0x00000000);
var drawnBitmap:Bitmap = new Bitmap(drawnBitmapData);
stage.addEventListener(MouseEvent.MOUSE_MOVE,maskMove);
stage.addEventListener(MouseEvent.ROLL_OUT, maskOut);
stage.addEventListener(MouseEvent.ROLL_OVER,maskOver);
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
function startDrawing(e:MouseEvent):void {
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
doDraw=true;
}
function stopDrawing(e:MouseEvent):void {
doDraw=false;
resumeDrawing = false;
}
function maskOut(e:Event):void {
if (doDraw){
resumeDrawing = true;
}
}
function maskOver(e:MouseEvent):void {
if (resumeDrawing){
resumeDrawing = false;
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
}
function maskMove(e:MouseEvent):void {
if (doDraw && !resumeDrawing){
eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
drawnBitmapData.fillRect(drawnBitmapData.rect, 0x00000000);
drawnBitmapData.draw(eraserClip , new Matrix(), null, BlendMode.NORMAL);
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
erasableBitmapData.draw(drawnBitmap, new Matrix(), null, BlendMode.ERASE);
}
e.updateAfterEvent();
}
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event):void {
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
}
I have a code to erase a masked movieclip. (credits here)
I would like to know how I can check if the whole movieclip is been erased.
So I thought I had to check if the BitmapData is empty, but I could be terribly wrong!
How can I check if every pixel of the movieclip has been erased?
Of course my example below is wrong, but I think it has to be something like that.
if (erasableBitmapData = empty)
{
trace("empty")
}
var lineSize:Number=40;
var doDraw:Boolean=false;
var resumeDrawing:Boolean=false;
var erasableBitmapData:BitmapData = new BitmapData(700, 500, true, 0xFFFFFFFF);
var erasableBitmap:Bitmap = new Bitmap(erasableBitmapData);
erasableBitmap.cacheAsBitmap = true;
addChild(erasableBitmap);
maskee.cacheAsBitmap = true;
maskee.mask = erasableBitmap;
var eraserClip:Sprite = new Sprite();
initEraser();
function initEraser():void {
eraserClip.graphics.lineStyle(lineSize,0xff0000);
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
var drawnBitmapData:BitmapData = new BitmapData(700, 500, true, 0x00000000);
var drawnBitmap:Bitmap = new Bitmap(drawnBitmapData);
stage.addEventListener(MouseEvent.MOUSE_MOVE,maskMove);
stage.addEventListener(MouseEvent.ROLL_OUT, maskOut);
stage.addEventListener(MouseEvent.ROLL_OVER,maskOver);
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
function startDrawing(e:MouseEvent):void {
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
doDraw=true;
}
function stopDrawing(e:MouseEvent):void {
doDraw=false;
resumeDrawing = false;
}
function maskOut(e:Event):void {
if (doDraw){
resumeDrawing = true;
}
}
function maskOver(e:MouseEvent):void {
if (resumeDrawing){
resumeDrawing = false;
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
}
function maskMove(e:MouseEvent):void {
if (doDraw && !resumeDrawing){
eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
drawnBitmapData.fillRect(drawnBitmapData.rect, 0x00000000);
drawnBitmapData.draw(eraserClip , new Matrix(), null, BlendMode.NORMAL);
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
erasableBitmapData.draw(drawnBitmap, new Matrix(), null, BlendMode.ERASE);
}
e.updateAfterEvent();
}
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event):void {
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以检查是否
getColorBoundsRect
返回一个宽度和高度为0
的矩形,用于表示您认为“空”的颜色,设置findColor
参数设置为 false。还有其他方法可以做到这一点,但这至少比检查每个像素快很多倍。findColor
参数的默认值 true 为您提供一个矩形,其中包含(pixelColor & mask) == emptyColor
为 true 的所有像素。处理 alpha 值时,可以使用0xFF000000
掩码来忽略像素的 rbg 值并仅检查其 alpha 值。因此,掩码0xFF000000
和颜色0xFF000000
将匹配所有完全不透明的像素,而掩码0xFF000000
和颜色0x00000000
> 将匹配所有完全透明的像素。正如 meddlingwithfire 所指出的,这在这里不起作用。通过将findColor
设置为 false,此过程有点相反,以便矩形将包含所有不使用空颜色的像素。对于不包含其他颜色的位图,结果将是面积为0
的矩形。从技术上讲,黑色透明像素
0x00000000
和红色透明像素0x00FF0000
之间存在差异 - 但没有明显的差异(两者都是不可见的),因此您应该忽略rgb 值完全正确,就像我在示例中使用该特定掩码所做的那样。You can check if
getColorBoundsRect
returns an rectangle with an width and height of0
for the colour you consider as 'empty', setting thefindColor
argument to false. There are other ways to do this, but this is at least many times faster than checking every single pixel.The default value of true for the
findColor
argument gives you an rectangle that encloses all pixels for those(pixelColor & mask) == emptyColor
is true. When dealing with alpha values, a mask of0xFF000000
can be used to ignore rbg values of a pixel and to only check its alpha value. So the mask0xFF000000
and the colour0xFF000000
would match all fully opaque pixels, while the mask0xFF000000
and the colour0x00000000
would match all fully transparent pixels. As meddlingwithfire pointed out, this won't do the job here. By settingfindColor
to false, this process is kind of reversed so that the rectangle will enclose all pixels that are not using the empty colour. For bitmaps containing no other colours, the result will be a rectangle with an area of0
.Technically there is a difference between a black transparent pixel
0x00000000
and for example a red transparent pixel0x00FF0000
- but there is no visible difference (both are invisible) so you should ignore the rgb values completely, as I did in the example by using that particular mask.创建基线“空”BitmapData 实例。使用 BitmapData 的比较方法,传入“可能为空”的 BitmapData。您将获得一个新的 BitmapData 引用,其中包含两者之间的像素差异。使用新的 BitmapData 引用,您可以访问直方图方法来获取每个通道的所有计数的列表。如果空 BitmapData 实例和“可能为空”BitmapData 实例完全相同,那么您的直方图通道将具有 BitmapData 中的像素总数作为每个通道的零索引中的计数(因为情况下的 BitmapData 差异)相同的数据将填充 0x00000000 像素)。
也应该相对较快,因为您可以依靠 AS 引擎来查看每个像素,而不必手动调用昂贵的 getPixel() 方法。
使用颜色边界方法可能会导致误报。如果您的位图在左上角和左下位置相同,那么您的颜色边界矩形将包含整个区域,即使中间的所有像素可能完全不同。
Create a baseline "empty" BitmapData instance. Use that BitmapData's compare method, passing in your "potentially empty" BitmapData. You'll get a new BitmapData reference that has the pixel differences between the two. Using that new BitmapData reference, you can access the histogram method to get a list of all the counts for every channel. If the empty BitmapData instance and the "potentially empty" BitmapData instance are exactly the same, then your histogram channel will have the total number of pixels in your BitmapData as the count in the zero index of each channel (since the BitmapData difference in the case of equal data would be filled with 0x00000000 pixels).
Should be relatively quick too, as you can rely on the AS engine to look at each pixel as opposed to having to manually call the expensive getPixel() method.
Using the color bounds approach can lead to false-positives. If your bitmaps are the same in the upper-left and lower-left positions then your color bounds rect will encompass the entire area, even though all of the pixels in-between could be completely different.
BitmapData.compare(BitmapData)
函数返回一个新的BitmapData
,其中包含调用的两个BitmapData
之间的差异,或者如果BitmapData >BitmapData
对象是等效的(具有相同的宽度、高度和相同的像素值),该方法返回数字 0。这意味着您可以使用以下代码来检查DisplayObject
是否包含图形<一href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#draw%28%29" rel="nofollow">draw() 文档
compare() 文档
The
BitmapData.compare(BitmapData)
function returns either a newBitmapData
containing the difference between the the calling twoBitmapData
s, or if theBitmapData
objects are equivalent (with the same width, height, and identical pixel values), the method returns the number 0. Meaning you could use the following to check if aDisplayObject
contains graphicsdraw() documentation
compare() documentation