问题描述:

The situation is, this resize code has always worked for me because I was using local images. I am now using a third party admin which feeds images through an application/octet-stream.

Whereas previously, I was loading the image with the Loader::load method but I am currently using the Loader::loadBytes to load the binary data because I am being fed a stream instead of an image/jpeg.

By switching to the stream, the code now fails to get past this line:

resizedImageData.copyPixels(e.currentTarget.getChildAt(0).bitmapData, cropRect, new Point(0, 0));

In this snippet:

 if((postcardWidth != postcardImage.width || postcardHeight != postcardImage.height) ) {

ExternalInterface.call( "console.log" , "IF");

var resizedImageData:BitmapData = new BitmapData(postcardWidth, postcardHeight);

ExternalInterface.call( "console.log" , "IF2");

var cropRect:Rectangle = new Rectangle(e.currentTarget.width / 2 - postcardWidth / 2, e.currentTarget.height / 2 - postcardHeight / 2, postcardWidth, postcardHeight);

ExternalInterface.call( "console.log" , "IF3");

resizedImageData.copyPixels(e.currentTarget.getChildAt(0).bitmapData, cropRect, new Point(0, 0));

ExternalInterface.call( "console.log" , "IF4");

var resizedImage:Bitmap = new Bitmap(resizedImageData);

ExternalInterface.call( "console.log" , "IF5");

postcardFront.addChild(resizedImage);

ExternalInterface.call( "console.log" , "IF6");

} else {

ExternalInterface.call( "console.log" , "ELSE");

postcardFront.addChild(postcardImage);

}

The postcardWidth is always 680, the postcardImage.width is 600, the postcardHeight is 442, and the postcardImage.height is 429.

It seems like the only culprit could be inconsistent bitmapData?

I have compared the working jpeg and the non-working jpeg using diff and opened them up both in vim and they start with the same character, end with the same character, and look 100% identical and span the same # of lines ( binary data ).

Does anyone have a clue why that line would work on one image and not the other?

MORE CODE

The loadBytes method is here: http://pastie.org/private/h463eu7cbx1vnhtxzq8xyg . This snippet is in an external .as file.

This code is from the fla, and is more of the code from the original snippet I pasted way up above in the question: http://pastie.org/private/vmwp4sw8urupdx91qny4w

网友答案:

Ok, after taking the code you've pasted at pastie.org, I recreated the Image class on my end and ran some tests. Three things seem to be the problem. The first one is the line:

e.currentTarget.getChildAt(0).bitmapData

It's the Image class that sends out the Event.COMPLETE, meaning that it's the currentTarget. The first child, from what I gather from that class, is the Loader object that you add. Loader doesn't have a bitmapData object, so this one will throw a "can't access property from null object error".

The second thing is that, assuming that you're meant to be targeting the Image object here and the bitmapData is the BitmapData object that you create in the function makeBitmapData() (from http://pastie.org/private/h463eu7cbx1vnhtxzq8xyg), there's no public access to the BitmapData. In my version of the class, I added a getter.

Third is that the Event.COMPLETE event is dispatched before the call to makeBitmapData(), meaning that even if you could access it, it'd be null.

As you're using ExternalInterface to log your messages, I'm assuming this is running in the browser and you don't have the debug Flash player running, so you won't see the errors for bitmapData being null, and thus one of the parameters in the copyPixels call being null (which would throw an exception halting the progress of the swf).

The Image class I used if you want to test this (it works on my end):

package  
{
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.net.URLRequest;
    import flash.net.URLStream;
    import flash.utils.ByteArray;

    public class Image extends Sprite 
    {

        private var m_loader:Loader     = null;
        private var m_bmd:BitmapData    = null;
        private var m_bytes:ByteArray   = null;
        private var m_stream:URLStream  = null;

        public function get bitmapData():BitmapData { return this.m_bmd; }

        public function Image() 
        {
            trace( "Creating a new image" );
        }

        public function loadBytes( s:String = null ):void 
        {
            trace( "Loading image '" + s + "'" );
            // FOR EASY TESTING ONLY:
            if ( s == null ) 
                s = "http://onflex.org/flexapps/applications/ProgressiveImageLoading/jpg.jpg";        

            // create URLStream with listeners
            this.m_stream = new URLStream();
            this.m_stream.addEventListener( ProgressEvent.PROGRESS, this._onStreamProgress );

            // create Loader for later
            this.m_loader = new Loader();
            this.addChild( this.m_loader );

            // create new ByteArray instance
            this.m_bytes = new ByteArray();

            // start the show!
            this.m_stream.load( new URLRequest( s ) );
        }

        private function _onStreamProgress( e:ProgressEvent):void
        {
            trace( "PROGRESS: " +  e.bytesLoaded + " of " + e.bytesTotal + " loaded!" );

            if ( this.m_stream.connected ) 
                this.m_stream.readBytes( this.m_bytes, this.m_bytes.length );

            if ( this.m_bytes.length == e.bytesTotal ) 
            {
                trace( "Image loaded!" );

                // get rid of the event listeners to avoid re-firing 
                this.m_stream.removeEventListener( ProgressEvent.PROGRESS, this._onStreamProgress ); 

                this._onStreamComplete();   
            }
        }

        private function _onStreamComplete():void
        {
            this.m_loader.contentLoaderInfo.addEventListener( Event.INIT, this._makeBitmapData );
            this.m_loader.loadBytes( this.m_bytes );

            trace( "Stream complete, loading bytes" );
        }

        private function _makeBitmapData( e:Event ):void
        {
            trace( "Making bitmap data" );

            this.m_loader.contentLoaderInfo.removeEventListener( Event.INIT, _makeBitmapData );

            // set the bitmapData for the other public methods
            this.m_bmd = new BitmapData( this.m_loader.width, this.m_loader.height );
            this.m_bmd.draw( this );

            this.dispatchEvent( new Event( Event.COMPLETE ) );
        }

    }

}

And the Main class:

package  
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    public class Main extends Sprite
    {
        private var m_image:Image = null;

        public function Main() 
        {
            this.m_image = new Image();
            this.m_image.addEventListener( Event.COMPLETE, this._onImageComplete );
            this.m_image.loadBytes();
        }

        private function _onImageComplete( e:Event ):void
        {
            this.addChild( this.m_image );

            var w:Number = 150.0;
            var h:Number = 150.0;

            var resized:BitmapData = new BitmapData( w, h );
            var cropRect:Rectangle = new Rectangle( this.m_image.width / 2 - w / 2, this.m_image.height / 2 - h / 2, w, h );

            resized.copyPixels( this.m_image.bitmapData, cropRect, new Point );

            var resizedImage:Bitmap = new Bitmap( resized );
            resizedImage.x = 450.0;
            this.addChild( resizedImage );
        }

    }

}

Does that fix it?

相关阅读:
Top