Flash:调整图片大小时保持透明度

时间:2011-07-25 09:05:40

标签: flash flex transparency image

我在网站上使用闪存程序在传输之前调整图片大小,以保留我的带宽。

但是,当我尝试传输具有透明度的.png文件时,调整大小不会保持.png文件结果的透明度。 在......之后使用它是一个问题。

这段代码:

public class ImageStrip extends MovieClip
{
    var _img:Bitmap;
    public var _iHelper:imgHelper;
    public var fileName:String;

    public var isEncoding:Boolean=false;
    public var isDirty:Boolean = true;

    public var encodedByteArray:ByteArray;
    private var asyncEncoder:AsyncJPEGEncoder;
    private static const _MAX_WIDTH     : Number = 800;
    private static const _MAX_HEIGHT    : Number = 800;

    public function ImageStrip(img:Bitmap, fileName:String) {


        stripSelected.alpha=stripOver.alpha = 0;
        this.fileName=(fileName.substr(0, fileName.search("z-z-z-z")));
        var fSize:String = (fileName.substr(fileName.search("z-z-z-z") + 7));
        var fName:String;
        if (this.fileName.length<15)
             fName = this.fileName;
        else
            fName =  this.fileName.substr(0,14)+'.. ';
        fName += " "+fSize;

        removeBT.addEventListener(MouseEvent.CLICK, eventRemoveClicked);
        _img = new Bitmap(img.bitmapData);
        caption.text = fName;

        _iHelper = new imgHelper(_img);
        _iHelper.addEventListener("invalidate", eventImageInvalidated);
        addChild(_iHelper);
        _iHelper.resizePic(44, 44, true);
        _iHelper.x = _iHelper.y = 4;
        addEventListener(MouseEvent.CLICK, eventMouseClicked);
        addEventListener(MouseEvent.ROLL_OVER, eventOver);
        addEventListener(MouseEvent.ROLL_OUT, eventOut);
        addEventListener(Event.ADDED_TO_STAGE, onAdded);
        pbar.mode = ProgressBarMode.MANUAL;
        pbar.reset();
        pbar.setProgress(0, 1);
        doEncode();
    }

    public function onAdded(e:Event):void 
    {
        removeBT.label =  Local.getInstance().getString("remove");
    }

    public function eventImageInvalidated(e:*=null) {
        pbar.reset();
        pbar.visible = true;
        pbar.setProgress(0, 1);
        doEncode();
    }

    public function doEncode() {
        if (!asyncEncoder){
            asyncEncoder = new AsyncJPEGEncoder(90);
            asyncEncoder.addEventListener("complete", eventJpgComleted);
            asyncEncoder.addEventListener("progress", eventJpgProgress);
        }
        else {
            asyncEncoder.cancel();
        }
        var btData:BitmapData = _iHelper.resizeBitmapData(_MAX_WIDTH, _MAX_HEIGHT);
        isEncoding = true;
        encodedByteArray = asyncEncoder.encode(btData);
    }

    private function eventJpgComleted(e:*) {
        isEncoding = false;
        isDirty = false;
        pbar.visible = false;
    }
    private function eventJpgProgress(e:ProgressEvent) {
        //trace('Progress : : ' + e.bytesLoaded / e.bytesTotal);

        var pbar:ProgressBar = pbar as ProgressBar;
        pbar.value = (e.bytesLoaded / e.bytesTotal);
    }

    public function set isUploading(value:Boolean) {
        pbar.indeterminate = value;
        pbar.visible = value;
    }

    public function set selected(flag:Boolean) {
        if (flag)
            TweenLite.to(stripSelected, 0.6, { autoAlpha:1 } );
        else
            TweenLite.to(stripSelected, 0.6, { autoAlpha:0 } );
    }

    private function eventOver(e:MouseEvent) {
        TweenLite.to(stripOver, 0.6, { autoAlpha:1 } );
    }
    private function eventOut(e:MouseEvent) {
        TweenLite.to(stripOver, 0.6, { autoAlpha:0 } );
    }

    private function eventRemoveClicked(E:MouseEvent) {
        dispatchEvent(new Event("removeStrip", true, true));
    }

    private function eventMouseClicked(e:MouseEvent) {
        e.stopImmediatePropagation();
        // not the remove button ...
        if (!(e.target is Button))
            dispatchEvent(new Event("stripClicked", true, true));

    }

}

这个功能:

public class imgBox extends MovieClip
{
    public var _img                 : imgHelper;
    private var _MAX_WIDTH              : Number;
    private var _MAX_HEIGHT             : Number;
    private var boxFrame:MovieClip;
    private var statusMsg:TextField;

    public var byteData:ByteArray;

    [Embed(source="rotate_right.png")]
    [Bindable]
    public var iconSymbol1:Class; 
    [Embed(source="rotate_left.png")]
    [Bindable]
    public var iconSymbol2:Class;

    public function imgBox(w:Number,h:Number,_bitmap:Bitmap) 
    {
        _MAX_WIDTH = w;
        _MAX_HEIGHT = h;

        var borderColor:uint  = 0x666666;
        var borderSize:uint   = 1;
        var vMenu:verticalMenu;

        _img = new imgHelper(_bitmap);
        _img.addEventListener("invalidate", eventImageInvalidated);
        if ( _bitmap.width > _MAX_WIDTH || _bitmap.height > _MAX_HEIGHT ) 
             _img.resizePic(_MAX_WIDTH, _MAX_HEIGHT, false);

        boxFrame = new MovieClip;
        boxFrame.graphics.lineStyle(borderSize, borderColor);
        boxFrame.graphics.drawRect(0, 0, _img.width+4,_img.height+4);
        addChild(boxFrame);

        addChild(_img);
        boxFrame.x = 60 + _img.theImage.x;
        boxFrame.y = _img.theImage.y;
        _img.x = 62;
        _img.y = 2;

        //vMenu = new verticalMenu();
        //var myMenu:Array = new Array( { label:'Rotate', _function:eventRotateHit } );// ,
                                //  { label:'Upload', _function:eventUploadHit } );
        //vMenu.buildMenu(myMenu);



        var  button:Button = new Button();
        //button.label = Local.getInstance().getString("rotateright");
        button.setStyle("icon", iconSymbol1);

        button.width = 48;          
        button.height = 48;         
        button.addEventListener(MouseEvent.CLICK, eventRotateHit);
        addChild(button);

        var  buttonbis:Button = new Button();
        //buttonbis.label = Local.getInstance().getString("rotate");
        buttonbis.setStyle("icon", iconSymbol2);
        buttonbis.width = 48;           
        buttonbis.height = 48;
        buttonbis.y = 60;
        buttonbis.addEventListener(MouseEvent.CLICK, eventRotateHit2);
        addChild(buttonbis);

    }       

    private function eventImageInvalidated(e:Event) {
        e.stopImmediatePropagation();

        dispatchEvent(new Event("invalidate", true, true));// invalidate for re-encoding the image.

    }

    private function eventUploadHit(e:*) {
        trace('Upload Hit');
        this.dispatchEvent(new Event("uploadImage"));
    }

    public function showStatus(msg:String) {
            TweenLite.to(boxFrame, 0.5, { height: _img.height + 24 } );
            var vMenu:verticalMenu = new verticalMenu();;
            if (statusMsg){
                removeChild(statusMsg);
                statusMsg = null;
            }
            statusMsg = new TextField();
            statusMsg.htmlText = msg;
            statusMsg.styleSheet = vMenu._textStyleSheet;
            statusMsg.width = _img.width;
            addChild(statusMsg);
            statusMsg.y = _img.height + 2;
            statusMsg.x = boxFrame.x + 10;

    }

    public function hideStatus(msg:String = "") {
            if (statusMsg){
                removeChild(statusMsg);
                statusMsg = null;
            }
            TweenLite.to(boxFrame, 0.5, { height: _img.height + 4 } );
    }

    private function eventRotateHit(e:*) {
        trace('rotate Image');
        if (statusMsg){
                removeChild(statusMsg);
                statusMsg = null;
            }

        _img.rotate(Math.PI / 2);
        _img.resizePic(_MAX_WIDTH, _MAX_HEIGHT, false);
        boxFrame.width = _img.width + 4;
        boxFrame.height = _img.height + 4;

        boxFrame.x = 60 + _img.theImage.x;
        boxFrame.y = _img.theImage.y;

    }

    private function eventRotateHit2(e:*) {
        trace('rotate Image');
        if (statusMsg){
                removeChild(statusMsg);
                statusMsg = null;
            }

        _img.rotate(Math.PI/-2);
        _img.resizePic(_MAX_WIDTH, _MAX_HEIGHT, false);
        boxFrame.width = _img.width + 4;
        boxFrame.height = _img.height + 4;

        boxFrame.x = 60 + _img.theImage.x;
        boxFrame.y = _img.theImage.y;           

    }

    public function dispose() {

    }

    public function prepare(w:Number, h:Number, q:Number) {
        var btData:BitmapData = _img.resizeBitmapData(w, h);
        byteData = new JPGEncoder(q).encode(btData);

    }

}

这里是imgHelper代码:

public class imgHelper extends MovieClip
{
    public var tt:TextField;
    public var theImage:Bitmap;
    private var myMask:MovieClip;


    private var _boxDimW:Number;
    private var _boxDimH:Number;




    public function imgHelper(img:Bitmap=null) 
    {
        theImage = img;
        if (theImage)
            addChild(theImage);
         tt = new TextField;
        tt.text = '0%';
    /*  addChild(tt);*/

    }

    public override function get width():Number {
        return theImage.width;
    }

    public override function get height():Number {
        return theImage.height;
    }
    public  function get _scaleX():Number {
        return theImage.scaleX;
    }
    public  function set _scaleX(sx) {
         theImage.scaleX = sx;
    }

    public  function get _scaleY():Number {
        return theImage.scaleY;
    }
    public  function set _scaleY(sy:Number) {
         theImage.scaleY = sy;
    }

    public function load(url:String)
    {
        //trace('loading : ' + url);
        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, picLoaded);
        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errLoading);
        loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
        var lContext:LoaderContext = new LoaderContext(true);



        var request:URLRequest = new URLRequest(url);
        try {
            loader.load(request,lContext);


        } catch (error:Error) {
            trace("Unable to load requested document.");
        }

    }
    private function progress(e:ProgressEvent)
    {
        tt.text = Math.round(e.bytesLoaded /e.bytesTotal *100) + '%';
    }

    private function errLoading(e:*)
    {
        tt.visible = false;
        dispatchEvent(new Event("imgLoaded",true,true));
    }

    private function picLoaded(e:*)
    {
        var picLoader:Loader = Loader(e.target.loader);
        theImage = Bitmap(picLoader.content);
        addChild(theImage);

        tt.visible = false;
        dispatchEvent(new Event("imgLoaded",true,true));
    }

    public function resizePic(rW:Number,rH:Number,crop:Boolean=false)
    {
        var img = theImage;
        _boxDimW = rW;
        _boxDimH = rH;

        if (img.width > img.height)
        {
            img.width = rW;
            img.height = img.height * img.scaleX;
        }
        else
        {
            img.height = rH;
            img.width = img.width * img.scaleY;
        }


        if (crop)
        {
            if (img.width < img.height)
            {
                var oldScaleX = img.scaleX;
                img.width = rW;
                img.scaleY += img.scaleX-oldScaleX;

            }
            else
            {
                var oldScaleY = img.scaleY;
                img.height = rH;
                img.scaleX += img.scaleY-oldScaleY;

            }

            maskIt(rW, rH);

        }
        else {
            if (img.height < img.width) {
                img.y=(rH-img.height)/2
            }
            else {
                img.x=(rW-img.width)/2

            }
        }



    }



    public function resizeBitmapData (rW:Number, rH:Number):BitmapData {
        var img:Bitmap = new Bitmap(theImage.bitmapData);
        trace('resize bitmap : ' + img.height + '-' + img.width);
        trace('resize bitmap : ' + rH + '-' + rW);
        if (img.width > img.height) {
                if (img.height>rH)
                    rH = img.height * (rW / img.width);
                else{ // do not resize
                    rH = img.height;
                    rW = img.width;
                }
        }
        else {
            if (img.width>rW)
                rW = img.width * (rH / img.height);
            else{ // do not resize
                    rH = img.height;
                    rW = img.width;
                }

        }

        var bmpData:BitmapData = new BitmapData(rW, rH);
        var scaleMatrix:Matrix = new Matrix( rW / img.width , 0, 0, rH / img.height   , 0,0);
        var colorTransform:ColorTransform = new ColorTransform();
        bmpData.draw(theImage, scaleMatrix , colorTransform, null, null, true);
        return (bmpData);
    }

    public function rotate(dir:Number) {


        var workingImage:Bitmap = new Bitmap(theImage.bitmapData.clone());
        var bmpData:BitmapData = new BitmapData(workingImage.height, workingImage.width);
        if (dir > 0)
            {
                var transMatrix:Matrix = new Matrix(Math.cos(dir),Math.sin(dir),-Math.sin(dir),Math.cos(dir), workingImage.height,0);
            }
            else
            {
                var transMatrix:Matrix = new Matrix(Math.cos(dir),Math.sin(dir),-Math.sin(dir),Math.cos(dir),0, workingImage.width);
            }
        var colorTransform:ColorTransform = new ColorTransform();
        bmpData.draw(workingImage, transMatrix, colorTransform, null, null, true);
        TweenLite.to(theImage, 0.5, { autoAlpha:0 } );
        //removeChild(theImage);
        theImage = new Bitmap(bmpData);
        addChild(theImage);
        //trace(theImage.y + '--' + theImage.x+'--'+theImage.height+'--'+theImage.width);
        if (theImage.height < theImage.width) {
                theImage.y += (_boxDimH - theImage.height) / 2
            }
            else {
                theImage.x +=(_boxDimW-theImage.width)/2

            }


        theImage.alpha = 0;
        TweenLite.to(theImage, 1, { autoAlpha:1 } );
        trace('sending event !');
        dispatchEvent(new Event("invalidate", true, true));// invalidate for re-encoding the image.
    }


    public function maskIt(w:Number, h:Number)
    {
        if (myMask) {
            removeChild(myMask);
            myMask = null;
        }
        myMask = new MovieClip();
        myMask.graphics.beginFill(0xFFCC00);
        myMask.graphics.drawRect(0, 0, w,h);
        addChild(myMask);
        this.mask = myMask;
    }

    public function dispose() {

    }

} 

AsyncJPGEncoder:

package Classes.utils
{
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
import flash.utils.setInterval;
import flash.utils.clearInterval;
import com.adobe.images.JPGEncoder;
import com.adobe.images.BitString;

[Event(name="progress", type="flash.events.ProgressEvent")]
[Event(name="complete", type="flash.events.Event")]
[Event(name="cancel", type="flash.events.Event")]

public class AsyncJPEGEncoder extends JPGEncoder implements IEventDispatcher
{
    private var _dispatcher:EventDispatcher;
    private var _encodeTimer:int;
    private var DCY:Number;
    private var DCU:Number;
    private var DCV:Number;
    private var _ypos:int;
    public var attachedImageStrip:Number = -1;

    public function AsyncJPEGEncoder(quality:Number=50)
    {
        super(quality);
        _dispatcher = new EventDispatcher(this);
    }

    /**
     * Created a JPEG image from the specified BitmapData
     *
     * @param image The BitmapData that will be converted into the JPEG format.
     * @return a ByteArray representing the JPEG encoded image data.
     * @langversion ActionScript 3.0
     * @playerversion Flash 9.0
     * @tiptext
     */ 


    override public function encode(image:BitmapData):ByteArray
    {
        // Initialize bit writer
        byteout = new ByteArray();
        bytenew=0;
        bytepos=7;

        // Add JPEG headers
        writeWord(0xFFD8); // SOI
        writeAPP0();
        writeDQT();
        writeSOF0(image.width,image.height);
        writeDHT();
        writeSOS();

        // Encode 8x8 macroblocks
        DCY=0;
        DCU=0;
        DCV=0;
        bytenew=0;
        bytepos=7;

        _ypos = 0;
        flash.utils.clearInterval(_encodeTimer);
        _encodeTimer = flash.utils.setInterval(doEncode, 1, image);


        return byteout;

    }
    import flash.display.Stage;

    private function doEncode(image:BitmapData):void 
    {
        for (var xpos:int=0; xpos<image.width; xpos+=8) 
        {
            RGB2YUV(image, xpos, _ypos);
            DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
            DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
            DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
        }
        _ypos += 8;

        var e:ProgressEvent =  new ProgressEvent(ProgressEvent.PROGRESS);
        if (_ypos<image.height)
        {
            e.bytesLoaded = _ypos;
            e.bytesTotal = image.height;
            dispatchEvent(e);
        }
        else
        {
            flash.utils.clearInterval(_encodeTimer);
            e.bytesLoaded = image.height;
            e.bytesTotal = image.height;
            dispatchEvent(e);
            finishEncode();
        }

    }

    private function finishEncode():void 
    {
        // Do the bit alignment of the EOI marker
        if ( bytepos >= 0 ) {
            var fillbits:BitString = new BitString();
            fillbits.len = bytepos+1;
            fillbits.val = (1<<(bytepos+1))-1;
            writeBits(fillbits);
        }

        writeWord(0xFFD9); //EOI
        //return byteout;

        var e:Event = new Event(Event.COMPLETE);
        dispatchEvent(e);

    }

    public function cancel():void 
    {
        var e:Event = new Event(Event.CANCEL);
        dispatchEvent(e);

        flash.utils.clearInterval(_encodeTimer);
    }

    public function getBytes():ByteArray
    {
        return byteout;
    }


    public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
        _dispatcher.addEventListener(type, listener, useCapture, priority);
    }

    public function dispatchEvent(evt:Event):Boolean{
        return _dispatcher.dispatchEvent(evt);
    }

    public function hasEventListener(type:String):Boolean{
        return _dispatcher.hasEventListener(type);
    }

    public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
        _dispatcher.removeEventListener(type, listener, useCapture);
    }

    public function willTrigger(type:String):Boolean {
        return _dispatcher.willTrigger(type);
    }


}
}

非常感谢你的帮助!

佛瑞德

1 个答案:

答案 0 :(得分:0)

正如我在评论中提到的,如果你需要输出透明度,你可能应该使用PNG编码器而不是JPEG。

查看imgHelper类,有几个地方可以创建BitmapData对象,但是不指定它们应该允许透明度。要做到这一点,他们应该看起来像:

new BitmapData(width,height,true,0);

第三个参数是将透明度设置为true,第四个参数是删除背景颜色。