Problem Summery: I want an approach to mask images with given PNGs. However, the inner of some of the PNG images are transparent. After I set the PNG as a mask, the area of the masked image below the inner of the PNG is invisible.
PNG
Current effect
The problem is how to approach to the effect like this:
Target effect
Solution Summery: The method floodFill of class BitmapData provides me a way to achieve my goal. For a mask image, if the pixel is transparent or its color is #FFFFFF, the pixel of the masked image below the pixel are invisible; otherwise, they are visible. floodFill will perform a flood fill operation on an image starting at an (x, y) coordinate and filling with a certain color, it is similar to the paint bucket tool in various paint programs. Therefore, if the center pixel of PNG is transparent, I do a flood fill operation starting at the center coordinate with the color #FF000000. Now, the pixels of the masked image below the pixels of the inner of the shape will be visible.
Following is the source of ArbitraryPNGMask.mxml
- <?xml version="1.0" encoding="utf-8"?>
- <mx:Application
- xmlns:mx="http://www.adobe.com/2006/mxml"
- layout="horizontal"
- backgroundColor="#FFFFFF"
- paddingTop="0"
- paddingRight="0"
- paddingLeft="0"
- paddingBottom="0" viewSourceURL="srcview/index.html">
- <mx:Script>
- <![CDATA[
- import mx.core.UIComponent;
- import mx.events.FlexEvent;
- import mx.controls.Image;
- import mx.controls.listClasses.IListItemRenderer;
- private function initMask():void
- {
- var bitmapData:BitmapData = new BitmapData(picture.width,picture.height);
- bitmapData.floodFill(bitmapData.width/2,bitmapData.height/2,0xFF000000);
- maskImage.source = new Bitmap(bitmapData);
- }
- private function getMaskImage(data:Object):Bitmap
- {
- var itemRenderer:IListItemRenderer = maskList.itemToItemRenderer(data);
- var bitmap:Bitmap;
- var bitmapData:BitmapData;
- bitmapData = Bitmap(Image(itemRenderer).content).bitmapData.clone();
- var pixel:uint = bitmapData.getPixel32(int(bitmapData.width/2),int(bitmapData.height/2));
- // extract the alpha value from the given ARGB value.
- var alpha:uint = pixel >> 24;
- // if the center pixel is transparent, suppose the mask is a png
- // image consist of a closed shape, this will fill the inner of
- // the closed shape with the RGB color 0x000000 inorder to make
- // the image area below the inner visible.
- if(alpha == 0x00)
- bitmapData.floodFill(bitmapData.width/2,bitmapData.height/2,0xFF000000);
- bitmap = new Bitmap(bitmapData);
- return bitmap;
- }
- private function startDragging():void
- {
- oldMouseX = maskImage.mouseX;
- oldMouseY = maskImage.mouseY;
- maskImage.addEventListener(Event.ENTER_FRAME,doDrag);
- }
- private function endDragging():void
- {
- maskImage.removeEventListener(Event.ENTER_FRAME,doDrag);
- }
- private var oldMouseX:Number = 0;
- private var oldMouseY:Number = 0;
- private function doDrag(event:Event):void
- {
- var offsetX:Number = maskImage.mouseX - oldMouseX;
- var offsetY:Number = maskImage.mouseY - oldMouseY;
- maskImage.x += offsetX;
- maskImage.y += offsetY;
- }
- ]]>
- </mx:Script>
- <mx:XML id="masksDataSource"
- source="assets/masks.xml"/>
- <mx:List id="maskList"
- dataProvider="{masksDataSource.mask}"
- height="100%">
- <mx:itemRenderer>
- <mx:Component>
- <mx:Image
- source="{data.@path}"
- height="80"/>
- </mx:Component>
- </mx:itemRenderer>
- </mx:List>
- <mx:Canvas
- width="100%"
- height="100%">
- <mx:Image id="picture"
- source="assets/picture.jpg"
- mask="{maskImage}"
- cacheAsBitmap="true"
- creationComplete="initMask()"
- />
- <mx:Image id="maskImage"
- source="{getMaskImage(maskList.selectedItem)}"
- cacheAsBitmap="true"
- buttonMode="true"
- mouseChildren="false"
- mouseDown="startDragging();"
- mouseUp="endDragging();"/>
- </mx:Canvas>
- </mx:Application>

February 14th, 2009
Ntt.cc 








Posted in
Tags: 
RSS Feed
Email Feed
[...] Summery: Continue the sample posted before A Trick of Using PNGs to Mask Images, When you browse a web page rendered in HTML with fire fox, IE, etc., click the right button of [...]
How can we rotate and resize mask dynamically like in editors?
I have an image and a frame ( .png ) , how i can set the frame as a frame of my image? Please answer me , urgent!!!