如何从 BitmapData 中剪切出 Shape?

发布于 2024-10-06 07:42:24 字数 901 浏览 0 评论 0原文

我有一个填充形状,以及一个与形状边界框宽度和高度相同的 BitmapData。
我需要从 BitmapData 中剪切形状(基本上将 BitmapData 绘制到形状上...)[如下所示: https://i.sstatic.net/VhdAm.png]

我使用相当黑客的方法:

        public static function cutPoly(img:BitmapData, s:Shape, bounds:Bounds):BitmapData {
        var temp:BitmapData = new BitmapData(bounds.width, bounds.height, true);
        Main.inst.stageQuality("low"); //hack to kill anti-aliasing
        temp.draw(s,new Matrix());
        Main.inst.stageQuality("high"); // end hack

        //0xFF00FF00 is the color of the shape
        makeColTrans(temp,0xFF00FF00); //makes the color transparent :P
        //return temp;
        img.draw(temp);
        //img.draw(temp);
        temp.dispose();
        makeColTrans(img, 0xFFFFFFFF);
        return img;
    }

我想知道是否有更好的方法......一个不仅仅是黑客。

I have a filled Shape, and a BitmapData that is the same width and height as the Shape's bounding box.
I need to cut the Shape from the BitmapData (basically draw the BitmapData onto the shape...) [like so: https://i.sstatic.net/VhdAm.png]

I use the rather hackish method of:

        public static function cutPoly(img:BitmapData, s:Shape, bounds:Bounds):BitmapData {
        var temp:BitmapData = new BitmapData(bounds.width, bounds.height, true);
        Main.inst.stageQuality("low"); //hack to kill anti-aliasing
        temp.draw(s,new Matrix());
        Main.inst.stageQuality("high"); // end hack

        //0xFF00FF00 is the color of the shape
        makeColTrans(temp,0xFF00FF00); //makes the color transparent :P
        //return temp;
        img.draw(temp);
        //img.draw(temp);
        temp.dispose();
        makeColTrans(img, 0xFFFFFFFF);
        return img;
    }

I was wondering if there is a better method...one that isn't just a hack.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

七秒鱼° 2024-10-13 07:42:24

它也可以被视为黑客,但您可以在容器精灵中添加位图和(绘制的)形状,用形状掩盖位图并再次绘制生成的图像。您获得的唯一好处是使用运行时的本机绘图算法,并且只有当您的 makeColTrans 逐像素扫描整个位图时才会出现这种情况。

编辑代码示例:

    public static function cutPoly(sourceBitmapData:BitmapData, maskShape:Shape, bounds:Rectangle):BitmapData {
        // you might not need this, supplying just the sourceBitmap to finalBitmapData.draw(), it should be tested though.
        var sourceBitmapContainer:Sprite = new Sprite();
        sourceBitmapContainer.addChild(sourceBitmap);
        sourceBitmapContainer.addChild(maskShape);

        var sourceBitmap:Bitmap = new Bitmap(sourceBitmapData);
        maskShape.x = bounds.x;
        maskShape.y = bounds.y;
        sourceBitmap.mask = maskShape;

        var finalBitmapData:BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00ffffff);
        // or var finalBitmapData:Bitmap = new BitmapData(maskShape.width, maskShape.height); not too sure about the contents of the bounds...
        finalBitmapData.draw(sourceBitmapContainer);

        return finalBitmapData;
    }

It can also be considered hack but you can add the bitmap and the (drawn) shape in a container sprite, mask the bitmap with the shape and draw the resulting image again. The only benefit you'd gain would be using the runtime's native drawing algorithms and that is only the case if your makeColTrans scans the whole bitmap pixel by pixel.

edited for code sample:

    public static function cutPoly(sourceBitmapData:BitmapData, maskShape:Shape, bounds:Rectangle):BitmapData {
        // you might not need this, supplying just the sourceBitmap to finalBitmapData.draw(), it should be tested though.
        var sourceBitmapContainer:Sprite = new Sprite();
        sourceBitmapContainer.addChild(sourceBitmap);
        sourceBitmapContainer.addChild(maskShape);

        var sourceBitmap:Bitmap = new Bitmap(sourceBitmapData);
        maskShape.x = bounds.x;
        maskShape.y = bounds.y;
        sourceBitmap.mask = maskShape;

        var finalBitmapData:BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00ffffff);
        // or var finalBitmapData:Bitmap = new BitmapData(maskShape.width, maskShape.height); not too sure about the contents of the bounds...
        finalBitmapData.draw(sourceBitmapContainer);

        return finalBitmapData;
    }
累赘 2024-10-13 07:42:24

draw() 方法的第二个参数采用变换矩阵 - 您可以在此处指定偏移、旋转、倾斜等。然后使用该位图数据对象作为形状上 beginBitmapFill 的源。

the second argument of the draw() method takes a transform matrix - you can specify offsets, rotation, skew, etc here. then use that bitmapdata object as the source of beginBitmapFill on the shape.

霓裳挽歌倾城醉 2024-10-13 07:42:24

形状周围的颜色是否一致?如果是这样,您可以找到该彩色像素的第一个实例,并从该坐标用 0x00000000 填充位图数据,然后将结果绘制到新的透明位图数据。

编辑

这是使用阈值的另一个示例。它远非完美,但它确实让你迈出了一步。在本例中,“Tile”类只是您在问题中提供的带有链接 ID 的图像。

import flash.display.BitmapData;
import flash.geom.Point;
import flash.display.Bitmap;

var sample : Tile = new Tile();

var alphaBitmap : BitmapData = new BitmapData ( sample.width, sample.height, true, 0x00000000 );
    alphaBitmap .draw ( sample );
    alphaBitmap.threshold( alphaBitmap, alphaBitmap.rect, new Point(), "<", 0xFFEFEFEF, 0xFFFFFFFF, 0xFFFFFFFF );
    alphaBitmap.threshold( alphaBitmap, alphaBitmap.rect, new Point(), "!=", 0xFFFFFFFF, 0x00000000 );

    addChild ( new Bitmap ( alphaBitmap ) );

var source : Tile = new Tile();
var output : BitmapData = new BitmapData ( sample.width, sample.height, true, 0x00000000 );
    output.copyPixels( source, source.rect, new Point(), alphaBitmap );

var outputBitmap : Bitmap = new Bitmap ( output );
    outputBitmap.x = outputBitmap.width;

addChild ( outputBitmap );

Is the colour around the shape consistent? If so, you could find the first instance of that coloured pixel and floodFill() the bitmapdata with 0x00000000 from that coordinate, and then draw the result to a new transparent bitmapdata.

edit

Here's another example using thresholds. It's far from perfect, but it does get you part of the way there. In this case, the class "Tile" is just the image you provided in your question with a linkage ID.

import flash.display.BitmapData;
import flash.geom.Point;
import flash.display.Bitmap;

var sample : Tile = new Tile();

var alphaBitmap : BitmapData = new BitmapData ( sample.width, sample.height, true, 0x00000000 );
    alphaBitmap .draw ( sample );
    alphaBitmap.threshold( alphaBitmap, alphaBitmap.rect, new Point(), "<", 0xFFEFEFEF, 0xFFFFFFFF, 0xFFFFFFFF );
    alphaBitmap.threshold( alphaBitmap, alphaBitmap.rect, new Point(), "!=", 0xFFFFFFFF, 0x00000000 );

    addChild ( new Bitmap ( alphaBitmap ) );

var source : Tile = new Tile();
var output : BitmapData = new BitmapData ( sample.width, sample.height, true, 0x00000000 );
    output.copyPixels( source, source.rect, new Point(), alphaBitmap );

var outputBitmap : Bitmap = new Bitmap ( output );
    outputBitmap.x = outputBitmap.width;

addChild ( outputBitmap );
酒解孤独 2024-10-13 07:42:24

如果您希望仅使用 BitmapData 对象来执行此“cookie-cut”算法,请考虑以下内容:

var bmp:BitmapData = pSourceBmp.clone();
var alphaBmp:BitmapData = new BitmapData(shape.width, shape.height, true, 0);

alphaBmp.draw( shape );

var alphaOrigin:Point = new Point();
var pasteOrigin:Point = new Point();

bmp.copyPixels( bmp, bmp.rect, pasteOrigin, alphaBmp, alphaOrigin, true);

注意:此代码未经测试。

我在 Blitting 引擎中使用了类似的东西出于“cookie-cutting”的目的,它可以很好地从任何给定的矢量图形中提取形状。面具的有趣替代品。

If you're looking to do this "cookie-cut" algorithm mostly just out of BitmapData objects, consider this:

var bmp:BitmapData = pSourceBmp.clone();
var alphaBmp:BitmapData = new BitmapData(shape.width, shape.height, true, 0);

alphaBmp.draw( shape );

var alphaOrigin:Point = new Point();
var pasteOrigin:Point = new Point();

bmp.copyPixels( bmp, bmp.rect, pasteOrigin, alphaBmp, alphaOrigin, true);

NOTE: This code is not tested.

I've used something like this in a Blitting engine for "cookie-cutting" purpose, and it worked beautifully to extract shapes out of any given vector graphics. Interesting alternative to Masks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文