• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
Locked
0

ANE, iOS and BitmapData

Explorer ,
Dec 15, 2011 Dec 15, 2011

Copy link to clipboard

Copied

Is there any example of passing bitmap data into iOS and returning a modfified copy. I am trying to convert a bitmap into jpeg - similar to this example in Windows http://blog.magicalhobo.com/2011/09/12/air-3-native-extension-imageprocessor/ but it crashed every time. I am pretty sure I am doing something basic wrong but not been an iOS / Objective C programmer I am really just trying magic incantations and I can't find any good examples. Any help appreciated?

   

Sean

 

P.S. Below is my attempt:

 

FREObject encodeJPEG(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])

{

     FREObject     objectBitmapData = argv[0];

     FREBitmapData bitmapData;

     

     FREAcquireBitmapData(objectBitmapData, &bitmapData);

     

     int width       = bitmapData.width;

     int height      = bitmapData.height;

     int stride      = bitmapData.lineStride32 * 4;

     uint32_t* input = bitmapData.bits32;

     

     FREReleaseBitmapData(objectBitmapData);

     

     

     UIImage *myImage = [UIImage imageWithData:input];

     NSData *jpgData  = UIImageJPEGRepresentation(myImage, 0.9);    

 

     FREObject    objectByteArray = argv[1];

     FREByteArray byteArray;

     

     FREObject length;

     

     FRENewObjectFromUint32(jpgData.length, &length);

     

     FRESetObjectProperty(objectByteArray, (const uint8_t*) "length", length, NULL);

     

     FREAcquireByteArray(objectByteArray, &byteArray);

     

     memcpy(byteArray.bytes, jpgData.bytes, jpgData.length);

     FREReleaseByteArray(objectByteArray);

         

     return NULL;

}

 

TOPICS
Development

Views

4.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Explorer , Dec 16, 2011 Dec 16, 2011

Finale version - seems to work ok - encodes ok and I think cleans up after itself ok.

Sean

FREObject encodeJPEG( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] )

{

    FREObject       objectBitmapData = argv[ 0 ];

    FREBitmapData2  bitmapData;

   

    FREAcquireBitmapData2( objectBitmapData, &bitmapData );

   

    int width       = bitmapData.width;

    int height      = bitmapData.height;

    int stride      = bitmapData.lineStride32 * 4;

    uint32_t* input = bitmapData.bits32;

   

   

...

Votes

Translate

Translate
Contributor ,
Dec 15, 2011 Dec 15, 2011

Copy link to clipboard

Copied

Not sure, but I don't think you can access input and thus bitmapData.bits32 after you have called FREReleaseBitmapData().

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 15, 2011 Dec 15, 2011

Copy link to clipboard

Copied

This kinda works except reds are blues in jpeg and not sure I am releasing everything ok.

Thats tomorrows battle.

Sean

    FREObject encodeJPEG( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] ) 

    {

     FREObject       objectBitmapData = argv[ 0 ];

     FREBitmapData2  bitmapData;

   

     FREAcquireBitmapData2( objectBitmapData, &bitmapData );

   

     int width       = bitmapData.width;

     int height      = bitmapData.height;

     int stride      = bitmapData.lineStride32 * 4;

     uint32_t* input = bitmapData.bits32;

   

     // make data provider from buffer

     CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData.bits32, (width * height * 4), NULL);

   

     // set up for CGImage creation

     int                     bitsPerComponent    = 8;

     int                     bitsPerPixel        = 32;

     int                     bytesPerRow         = 4 * width;

     CGColorSpaceRef         colorSpaceRef       = CGColorSpaceCreateDeviceRGB();

     CGBitmapInfo            bitmapInfo          = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst;

     CGColorRenderingIntent  renderingIntent     = kCGRenderingIntentDefault;

     CGImageRef              imageRef            = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

       

     // make UIImage from CGImage

     UIImage *myImage = [UIImage imageWithCGImage:imageRef];   

     NSData* jpgData  = UIImageJPEGRepresentation( myImage, 0.9 );   

     FREReleaseBitmapData( objectBitmapData );

     FREObject    objectByteArray = argv[ 1 ];              

     FREByteArray byteArray;

     FREObject    length;

   

     FRENewObjectFromUint32( jpgData.length, &length );

     FRESetObjectProperty( objectByteArray, ( const uint8_t* ) "length", length, NULL );

     FREAcquireByteArray( objectByteArray, &byteArray );

   

     memcpy( byteArray.bytes, jpgData.bytes, jpgData.length );

   

     FREReleaseByteArray( objectByteArray );

       

     return NULL;

    }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 16, 2011 Dec 16, 2011

Copy link to clipboard

Copied

Finale version - seems to work ok - encodes ok and I think cleans up after itself ok.

Sean

FREObject encodeJPEG( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] )

{

    FREObject       objectBitmapData = argv[ 0 ];

    FREBitmapData2  bitmapData;

   

    FREAcquireBitmapData2( objectBitmapData, &bitmapData );

   

    int width       = bitmapData.width;

    int height      = bitmapData.height;

    int stride      = bitmapData.lineStride32 * 4;

    uint32_t* input = bitmapData.bits32;

   

    // make data provider from buffer

    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData.bits32, (width * height * 4), NULL);

   

    // set up for CGImage creation

    int                     bitsPerComponent    = 8;

    int                     bitsPerPixel        = 32;

    int                     bytesPerRow         = 4 * width;

    CGColorSpaceRef         colorSpaceRef       = CGColorSpaceCreateDeviceRGB();   

    CGBitmapInfo            bitmapInfo;

    if( bitmapData.hasAlpha )

    {

        if( bitmapData.isPremultiplied )

            bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst;

        else

            bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaFirst;           

    }

    else

    {

        bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst

    }

   

    CGColorRenderingIntent  renderingIntent     = kCGRenderingIntentDefault;

    CGImageRef              imageRef            = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    // make UIImage from CGImage

    UIImage *myImage = [UIImage imageWithCGImage:imageRef];   

    NSData* jpgData  = UIImageJPEGRepresentation( myImage, 0.9 );   

    FREReleaseBitmapData( objectBitmapData );

    FREObject    objectByteArray = argv[ 1 ];              

    FREByteArray byteArray;

    FREObject    length;

   

    FRENewObjectFromUint32( jpgData.length, &length );

    FRESetObjectProperty( objectByteArray, ( const uint8_t* ) "length", length, NULL );

    FREAcquireByteArray( objectByteArray, &byteArray );

   

    memcpy( byteArray.bytes, jpgData.bytes, jpgData.length );

   

    FREReleaseByteArray( objectByteArray );

       

    // release bits

    CGColorSpaceRelease(colorSpaceRef);

    CGImageRelease(imageRef);

    CGDataProviderRelease(provider);   

    return NULL;

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 11, 2012 Feb 11, 2012

Copy link to clipboard

Copied

Hi Sean,

this is exactly what I've been looking for. Do you have any plans to do a proper release with an ane and perhaps a sample of how to use it?

cheers,

Otto

ps. it would be really sweet if it was possible to supply a width and height argument as well so that you could resize images.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 12, 2012 Feb 12, 2012

Copy link to clipboard

Copied

Why you want use ANE ? this convertation may be you can do in AS ? Don't thinkg about that?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 12, 2012 Feb 12, 2012

Copy link to clipboard

Copied

Because doing it C is much, much faster.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 12, 2012 Feb 12, 2012

Copy link to clipboard

Copied

how much ? ) for a few seconds? )))

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 12, 2012 Feb 12, 2012

Copy link to clipboard

Copied

That depends on the size of your image and compression parameters. I'd estimate a factor of 10.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 13, 2012 Feb 13, 2012

Copy link to clipboard

Copied

It is painfully slow in AS - typically 30 seconds and more. This seems to be the consistent experience from others as well.

Sean

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 13, 2012 Feb 13, 2012

Copy link to clipboard

Copied

I stopped the work while waiting for Adobe to fix the issue with taking pictures on an iOS device crashing consistently. See below for wrapping AS code and usage example. Should be enough to get you bootstrapped.

Sean

package com.ticketsolve

{

          import flash.display.BitmapData;

          import flash.events.EventDispatcher;

          import flash.events.StatusEvent;

          import flash.external.ExtensionContext;

          import flash.utils.ByteArray;

 

          public class Extensions extends EventDispatcher

          {

                    //---------------------------------------------------------------------

                    //

                    // Constants

                    //

                    //---------------------------------------------------------------------

 

                    private static const EXTENSION_ID : String = "com.ticketsolve.extensions";

                      

                    //---------------------------------------------------------------------

                    //

                    // Private Properties.

                    //

                    //---------------------------------------------------------------------

 

                    private var context : ExtensionContext;

                      

                    //---------------------------------------------------------------------

                    //

                    // Public Methods.

                    //

                    //---------------------------------------------------------------------

                    

                    public function Extensions()

                    {

                              context = ExtensionContext.createExtensionContext( EXTENSION_ID, null );

                    }

 

                    public function encodeJPEG(image:BitmapData):ByteArray

                    {

                              var bytes:ByteArray = new ByteArray();

                              context.call('encodeJPEG', image, bytes);

                              return bytes;

                    }

                    

                    //---------------------------------------------------------------------

                    //

                    // Private Methods.

                    //

                    //---------------------------------------------------------------------

 

                    private function onExtensionHandler( event : StatusEvent ) : void

                    {

                              if( event.code == ExtensionsEvent.EXTENSION_EVENT )

                              {

                                        dispatchEvent( new ExtensionsEvent( event.level ) );

                                        context.removeEventListener( StatusEvent.STATUS, onExtensionHandler );

                              }

                    }

          }

}

<extension xmlns="http://ns.adobe.com/air/extension/2.5">

    <id>com.ticketsolve.extensions</id>

    <versionNumber>0.0.1</versionNumber>

    <platforms>

        <platform name="iPhone-ARM">

            <applicationDeployment>

                <nativeLibrary>libExtensions.a</nativeLibrary>

                <initializer>ExtInitializer</initializer>

                <finalizer>ExtFinalizer</finalizer>

            </applicationDeployment>

        </platform>

      <platform name="default">

        <applicationDeployment/>

      </platform>

    </platforms>

</extension>



public function scaledFile() : File


{



var file:File
        = File.applicationStorageDirectory.resolvePath( "paisti" + new Date().time + ".jpg" );



var stream:FileStream       = new FileStream()



var extensions : Extensions = new Extensions();







var bytes:ByteArray;







if( Capabilities.os.match( /iPhone/ ) )




bytes = extensions.encodeJPEG( original );



else




bytes = new JPEGEncoder().encode( original );











stream.open( file, FileMode.WRITE );



stream.writeBytes( bytes, 0, bytes.bytesAvailable );



stream.close();







bytes.clear();







return file;


}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Feb 13, 2012 Feb 13, 2012

Copy link to clipboard

Copied

LATEST

Thanks, but I already got it going by looking at the .net image resize ane.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines