Why is my resizing code failing?
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?
精彩评论