Вспышка: сохранить прозрачность при изменении размера изображения - PullRequest
1 голос
/ 25 июля 2011

Я использую флэш-программу на своем веб-сайте для изменения размера изображений перед передачей, чтобы сохранить пропускную способность.

Но, когда я пытаюсь передать файл .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 голосов
/ 25 июля 2011

Как я уже упоминал в комментариях, вам, вероятно, следует использовать кодировщик PNG, а не JPEG, если вам нужно вывести прозрачность.

Глядя на ваш класс imgHelper, есть пара мест, где вы создаете BitmapDataобъекты, но не указывайте, что они должны обеспечивать прозрачность.Для этого они должны выглядеть следующим образом:

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

Третий параметр устанавливает для прозрачности значение true, а четвертый - для удаления цвета фона.

...