Disclaimer: I'm not a flash developer but I'm trying to solve a flash issue. Please don't assume I'm intimately familiar with AS or Flash, because I'm not.
The dilemma I currently have is that I'm hosting a resource that is application/octet-stream
. In my Actionscript code, I'm using some library that ( from what I can recall ) does new Image
and loads a resource into that object which was created.
There is a method, loadImage(url)
which accepts a url and that's where you feed it the path to the image.
I do not have access to the loadImage
source code, so I don't know exactly what it does, but the working one loads the image fine because the Content-Type
is image/jpeg
. The non-working one ( this one I'm trying to fix ) doesn't because of the different Content-Type
.
I'm wondering if someone can tell me if I can make the flash basically parse the URI as if it were image/jpeg
, regardless of the Content-Type?
I do not have access to the source code at the moment, but I'm just throwing this out there to get input
If need be, I'll try and get some source code tomorrow
EDIT: Ok, I have access to the source now. Here's the part that loads the image:
postcardImage = new Image();
postcardImage.loadImage(imagePath);
I assume that Image
the constructor is native to flash/AS, but I haven't been able to google the loadImage
method so it must be custom, right?
Or could the Image constructor itself be custom? An extended version of the original Image
with loadImage
method and such?
Anyways, does anyone know how I can view the source code of loadImage
?
EDIT #2: I did an ack-grep
and found the source code for the loadImage
method defined in a library:
public class Image extends Sprite {
private var _source:String;
private var _loader:Loader;
private var _bmapData:BitmapData;
private var _loadedBytes:Number;
private var _totalBytes:Number;
public function Image() {
trace('IMAGE');
}
public function loadImage(s:String):void {
_source = s;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
_loader.contentLoaderInfo.addEventListener(Event.INIT, onLoading);
_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
_loader.load(new URLRequest(_source));
function onProgress(e:ProgressEvent):void {
_loadedBytes = e.target.bytesLoaded;
dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS));
if(!_totalBytes) {
setTotalBytes(e.target.bytesTotal);
}
}
function onLoading(e:Event):void {
_loader.contentLoaderInfo.removeEventListener(Event.INIT, onLoading);
}
function onLoaded(e:Event):void {
_bmapData = e.target.content.bitmapData;
addChild(e.target.content);
dispatchEvent(new Event(Event.COMPLETE));
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
}
}
public function getBmapData():BitmapData {
return _bmapData;
}
public function duplicate():Image {
var dup:Image = new Image();
dup.addChild(new Bitmap(_bmapData.clone()));
return dup;
}
public function getLoadedBytes():Number {
return _loadedBytes;
}
private function setTotalBytes(n:Number):void {
_totalBytes = n;
dispatchEvent(new Event("TOTALBYTES_SET"));
}
public function getT开发者_JAVA百科otalBytes():Number {
return _totalBytes;
}
}
Can anyone offer advice as to how I can do the loadBytes
on this? I was thinking of defining a custom method, loadResource
or something which can load regardless of Content-Type... or just create an optional parameter in the current load
method and inside, branch out based on what was passed.
I've been playing with ByteArray methods of late and this sounded fun. I've amended your Image class with a method for passing the URL of the octet-stream. Let me know how it works out!
note: I'm not setting the _loadedBytes and _totalBytes properties, but am drawing the loaded image to enable the public 'getBmapData' method.
package {
import flash.utils.ByteArray;
import flash.net.URLStream;
import flash.display.Bitmap;
import flash.net.URLRequest;
import flash.events.ProgressEvent;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
public class Image extends Sprite {
private var _source : String;
private var _loader : Loader;
private var _bmapData : BitmapData;
private var _loadedBytes : Number;
private var _totalBytes : Number;
private var _stream : URLStream;
private var _bytes:ByteArray;
public function Image() {
trace('IMAGE');
}
public function loadImage(s : String) : void {
_source = s;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
_loader.contentLoaderInfo.addEventListener(Event.INIT, onLoading);
_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
_loader.load(new URLRequest(_source));
function onProgress(e : ProgressEvent) : void {
_loadedBytes = e.target.bytesLoaded;
dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS));
if(!_totalBytes) {
setTotalBytes(e.target.bytesTotal);
}
}
function onLoading(e : Event) : void {
_loader.contentLoaderInfo.removeEventListener(Event.INIT, onLoading);
}
function onLoaded(e : Event) : void {
_bmapData = e.target.content.bitmapData;
addChild(e.target.content);
dispatchEvent(new Event(Event.COMPLETE));
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaded);
}
}
// ByteArray methods
// adapted from Ted Patrick's
// http://ted.onflash.org/2007/12/progressive-image-loading-with.php
public function loadBytes( s:String = "" ):void {
// FOR EASY TESTING ONLY:
if( s == "" ) s = "http://onflex.org/flexapps/applications/ProgressiveImageLoading/jpg.jpg";
// create URLStream with listeners
_stream = new URLStream();
_stream.addEventListener( ProgressEvent.PROGRESS , streamProgress );
// Not firing, so lets not use it...
//_stream.addEventListener( Event.COMPLETE , streamComplete );
// create Loader for later
_loader = new Loader();
// create new ByteArray instance
_bytes = new ByteArray();
// go ahead and add it to the display list
addChild( _loader );
// start the show!
_stream.load( new URLRequest(s) );
}
private function streamProgress(p : ProgressEvent) : void {
trace("PROGRESS: ", p.bytesLoaded, "of", p.bytesTotal );
if( _stream.connected ) _stream.readBytes(_bytes, _bytes.length );
if( _bytes.length == p.bytesTotal ) {
// get rid of the event listeners to avoid re-firing
_stream.removeEventListener( ProgressEvent.PROGRESS , streamProgress );
streamComplete();
}
}
private function streamComplete() : void {
_loader.loadBytes( _bytes );
_loader.contentLoaderInfo.addEventListener( Event.INIT, makeBitmapData );
}
private function makeBitmapData( e:Event ):void{
_loader.contentLoaderInfo.removeEventListener( Event.INIT, makeBitmapData );
// set the bitmapData for the other public methods
_bmapData = new BitmapData(_loader.width, _loader.height );
_bmapData.draw( this );
}
//-----
public function getBmapData() : BitmapData {
return _bmapData;
}
public function duplicate() : Image {
var dup : Image = new Image();
dup.addChild(new Bitmap(_bmapData.clone()));
return dup;
}
public function getLoadedBytes() : Number {
return _loadedBytes;
}
private function setTotalBytes(n : Number) : void {
_totalBytes = n;
dispatchEvent(new Event("TOTALBYTES_SET"));
}
public function getTotalBytes() : Number {
return _totalBytes;
}
}
}
Short answer: Yes.
I would assume that the code is using a Loader
object behind the scenes to do the actual image loading/retrieval (this is the standard way of doing such things). Loader objects support PNG, JPEG, and GIF (first frame only) formats.
Now, I'm not sure if Loaders use the content type of the response to guess the image format (I would guess not, but I could be wrong). I do know that Loaders have a loadBytes()
method which loads an image directly from its raw bytes -- the format sniffing only uses the image's actual data in that case, as there is no HTTP request directly involved. So, if it's really the content type that's the culprit, you could load the image separately as raw data, then get an image object from that raw data using loadBytes()
, bypassing the issue entirely.
We'd have to see the code to really know what's going on, of course.
精彩评论