2

I have a Flash / Actionscript 3 based desktop app wrapped in an *.exe using Zinc 4.0. I am using Flash Pro CS5.

I need to start saving very large image files locally. I have messed around with JPG Encoding these images before saving them to a local file via Zinc. I solved the actionscirpt timeout issue using This "asyncronous like" method. Encoding a 1.5 MP image takes about 5 seconds which is alright, but encoding an 8 MP image file takes about 40 seconds, which is not acceptable.

One idea I had is to save the BitmapData locally to a temporary Bitmap file (*.bmp), without having the end user to wait for JPG Encoding in Flash, and then use my already existing image processor (written in C#) to read the bitmap file and encode it without waiting on Flash to do it, effectively offloading the task away from the user.

I have used BitmapData.getPixels() to try and write the byte array directly to the file, using the same Zinc method as I do successfully with encoded JPGs, but the *.bmp file is unreadable. Are there some file headers that would need to be included in addition to the BitmapData getPixel()'s byte array to successfully save a bitmap image? If so how could I successfully add them to the byte array before writing to file?

Any guidance, clarification or other solutions much appreciated.

Charles
  • 50,943
  • 13
  • 104
  • 142
ToddBFisher
  • 11,370
  • 8
  • 38
  • 54
  • 1
    I think this link could help you : http://www.senocular.com/flash/actionscript/?file=ActionScript_3.0/com/senocular/images/BMPEncoder.as – Engineer Apr 03 '12 at 19:13
  • you may also want to look into writing a native extension and passing the bitmap data directly to c# – francis Apr 03 '12 at 22:17
  • if you're using the as3corelib for the `JPEGEncoder`, consider using the `PNGEncoder` instead - I've found it much faster. The `JPEGEncoder` gets ironically gets bogged down in the quality setting – divillysausages Apr 04 '12 at 21:22

2 Answers2

2

I've found a solution for my needs, and just in case others have similar needs:

To save an actual Bitmap (*.bmp) file, Engineer's suggested Btimap encoder class was awesome. Very fast on the actual encoding; however, since my file writing call in Zinc is synchronous and bitmap files are a lot larger than JPGs it really just moved my bottle neck from encoding to the file saving, so I decided to look elsewhere. If Zinc had an asynchronous binary file writing method that would not lock up the GUI I would have been happy, but until then this is not the solution for me.

I stumbled across a Flash Alchemy solution, with great results. Instead of waitint abour 40 seconds to encode an 8 MP image, it now only takes a few seconds. This is what I did:

  1. Downloaded the jpegencoder.swc from this page and saved it in my project directory
  2. Added the swc: Publish Settings > Flash (tab) > Script: Actionscript 3.0 "Settings..." button > Library path (tab)> and added that .swc with Link Type = "Merged into code"
  3. Then used it :

(below is my modified code with just the basics)

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
}

You may find this link useful as well: http://last.instinct.se/graphics-and-effects/using-the-fast-asynchronous-alchemy-jpeg-encoder-in-flash/640

ToddBFisher
  • 11,370
  • 8
  • 38
  • 54
1

my answer is late but maby it helps. i developed a AIR mobile app to save imgs from the device camera on the device and upload it to the server. since air 3.3 you have this bitmapdata encode functionality:

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();

the encode to jpg takes ~100ms on mobile devices in my tests.

greetings stefan

Stefan Habacher
  • 153
  • 1
  • 8
  • Great answer! :) I totally don't understand why people keep searching for any kind of 'encoders' - all of them work few times __slower__ than the native one. I've also used it few times and performance is amazing! – Andrey Popov May 14 '14 at 07:41