2012-04-03 21 views
2

Ich habe eine Flash/Actionscript 3-basierte Desktop-App in eine * .exe mit Zink 4.0 gewickelt. Ich verwende Flash Pro CS5.So speichern Sie BitmapData in Bitmap * .bmp-Datei oder viel schneller JPE Encoding-Methode

Ich muss beginnen, sehr große Bilddateien lokal zu speichern. Ich habe mit JPG-Encoding diese Bilder durcheinandergebracht, bevor Sie sie über Zink in einer lokalen Datei speichern. Ich habe das Problem mit der Aktion cirpt timeout unter Verwendung von This "asyncronous like" method gelöst. Die Kodierung eines 1,5-MP-Bildes dauert ungefähr 5 Sekunden, was in Ordnung ist, aber das Kodieren einer 8-MP-Bilddatei dauert ungefähr 40 Sekunden, was nicht akzeptabel ist.

Eine Idee war, die BitmapData lokal in einer temporären Bitmap-Datei (* .bmp) zu speichern, ohne dass der Endbenutzer auf JPG Encoding in Flash warten musste, und dann meinen bereits vorhandenen Image-Prozessor (in C# geschrieben)) um die Bitmap-Datei zu lesen und zu codieren, ohne auf Flash zu warten, um die Aufgabe effektiv vom Benutzer zu entfernen.

Ich habe BitmapData.getPixels() verwendet, um zu versuchen, das Bytearray direkt in die Datei zu schreiben, mit der gleichen Zinc-Methode wie ich erfolgreich mit codierten JPGs, aber die * .bmp-Datei ist nicht lesbar. Gibt es einige Dateiheader, die zusätzlich zum Bytearray von BitmapData getPixel() hinzugefügt werden müssen, um ein Bitmapbild erfolgreich zu speichern? Wenn ja, wie könnte ich sie erfolgreich zum Bytearray hinzufügen, bevor ich in die Datei schreibe?

Jede Anleitung, Klärung oder andere Lösungen sehr geschätzt.

+1

Ich denke, dieser Link könnte Ihnen helfen: http://www.senocular.com/flash/actionscript/?file=ActionScript_3.0/com/senocular/images/BMPEncoder.as – Engineer

+0

können Sie Auch wenn Sie eine native Erweiterung schreiben und die Bitmap-Daten direkt an C# – francis

+0

übergeben möchten, wenn Sie die as3corelib für den 'JPEGEncoder' verwenden, sollten Sie stattdessen' PNGEncoder' verwenden - ich habe es viel schneller gefunden. Der 'JPEGEncoder' wird ironischerweise in der Qualitätseinstellung steckengeblieben – divillysausages

Antwort

2

ich eine Lösung für meine Bedürfnisse gefunden haben, und für den Fall, andere haben ähnliche Bedürfnisse:

eine tatsächliche Bitmap (* .bmp) Datei zu speichern, Ingenieur vorgeschlagenen Btimap encoder class war fantastisch. Sehr schnell auf die tatsächliche Codierung; Da jedoch mein Aufruf zum Schreiben von Dateien in Zinc synchron ist und Bitmap-Dateien viel größer sind als JPGs, hat es wirklich nur meinen Flaschenhals von der Codierung zur Dateispeicherung bewegt, also entschied ich mich, woanders hin zu schauen. Wenn Zinc eine asynchrone Binärdatei-Schreibmethode hätte, die die GUI nicht sperren würde, wäre ich glücklich gewesen, aber bis dahin ist das nicht die Lösung für mich.

Ich bin über eine Flash Alchemy-Lösung gestolpert, mit großartigen Ergebnissen. Statt nach einer Wartezeit von 40 Sekunden, um ein 8-MP-Bild zu kodieren, dauert es jetzt nur noch ein paar Sekunden. Das ist, was ich tat:

  1. die jpegencoder.swc von this page heruntergeladen und gespeichert es in meinem Projektverzeichnis
  2. Added die SWC: Veröffentlichungseinstellungen> Flash (tab)> Script: Actionscript 3.0 „Einstellungen ... "button> Bibliothekspfad (tab)> und fügte hinzu, dass .swc mit Link Type = "Eingebunden in Code"
  3. verwendet Dann ist es:

(unten ist mein modifizierten Code nur mit den Grundlagen)

import flash.utils.ByteArray; 
import flash.display.BitmapData; 
import cmodule.aircall.CLibInit; //Important: This namespace changed from previous versions 

var byteArrayResults:ByteArray; //Holds the encoded byte array results 

public static function startEncoding(bitmapData:BitmapData):void { 

    var jpeginit:CLibInit = new CLibInit();  // get library 
    var jpeglib:Object = jpeginit.init();  // initialize library exported class to an object 

    var imageBA:ByteArray = bitmapData.getPixels(bitmapData.rect); //Getpixels of bitmapData 
    byteArrayResults = new ByteArray(); 
    imageBA.position = 0; 
    jpeglib.encodeAsync(encodeComplete, imageBA, byteArrayResults, bitmapData.width, bitmapData.height, 80); 
} 

private static function encodeComplete(thing:*):void 
{ 
    // Do stuff with byteArrayResults 
} 

Sie können diesen Link nützlich finden: http://last.instinct.se/graphics-and-effects/using-the-fast-asynchronous-alchemy-jpeg-encoder-in-flash/640

1

meine Antwort spät ist aber maby es hilft. Ich habe eine AIR Mobile App entwickelt, um Imgs von der Gerätekamera auf dem Gerät zu speichern und auf den Server hochzuladen. da Luft 3.3 Sie haben diese BitmapData- kodieren Funktionalität:

var ba:ByteArray = new ByteArray(); 
var bd:BitmapData = new BitmapData(_lastCameraPhotoTmpBmp.width, _lastCameraPhotoTmpBmp.height); 
bd.draw(_lastCameraPhotoTmpBmp); 
bd.encode(new Rectangle(0, 0, 1024, 768), new JPEGEncoderOptions(80), ba); 

var localFile:File = File.applicationStorageDirectory.resolvePath("bild.jpg"); 
var fileAccess:FileStream = new FileStream(); 
fileAccess.open(localFile, FileMode.WRITE); 
fileAccess.writeBytes(ba, 0, ba.length); 
fileAccess.close(); 

die Encodierung zu jpg nimmt ~ 100ms auf mobilen Geräten in meinen Tests.

Grüße stefan

+0

Tolle Antwort! :) Ich verstehe überhaupt nicht, warum Leute nach irgendwelchen 'Encodern' suchen - alle arbeiten ein paar Mal weniger als die ursprüngliche. Ich habe es auch einige Male benutzt und die Leistung ist erstaunlich! –