June 7, 2014

Canon EOSLib. Update

CanonEOSLib was developed for a very specific project and to interact only with the Canon EOS1100D. Later we tried to update the code and communicate with more cameras but due to the differences between them, some functionalities are affected and don´t work as expected.

The more problematic functionality is related with the EVF (electronic viewfinder) capture. Using the libraries provided by the camera manufacturer, the extension executes commands that are passed from the Adobe AIR runtime. The commands are executed in a separate thread to avoid overloading the main thread and to keep a good user experience when the camera is working.

To understand a bit better look at this graphic:

getEVF function scheme

getEVF function scheme

Asynchronous thread code:
Download live preview image from the camera, process it and save in a global native object.

_model->setEvfBitmap( targetBitmap);

If a new image is ready to download, the native extension dispatch an event to notify runtime Adobe AIR.

FREDispatchStatusEventAsync(  _ctx, ( uint8_t*) "downloadEVF", (const uint8_t*) event.c_str() );

Code in main thread:
Method to copy bytes from native bitmap.

FREObject getEVF( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] )
{
	BOOL r = 0;
	FREObject result;
	FREBitmapData2 bitmap_descriptor;
	FREObject freBitmap = argv[0];

	Bitmap* targetBitmap = _model->getEvfBitmap();

	if( targetBitmap == NULL ) 
	{
		FRENewObjectFromBool( 0, &result ); 
		return result;
	}

	// Get AS3 bitmap content.
	FREAcquireBitmapData2( freBitmap, &bitmap_descriptor );
	uint32_t* input = bitmap_descriptor.bits32;

	if( bitmap_descriptor.isInvertedY == 1 ) 
          targetBitmap->RotateFlip( RotateNoneFlipY ); //is inverted
        int pixelSize = 4;
	Rect rect( 0, 0, bitmap_descriptor.width, bitmap_descriptor.height );
	BitmapData* pBmData = new BitmapData;

	targetBitmap->LockBits( &rect, ImageLockModeRead, PixelFormat32bppARGB,pBmData );

	for (int y = 0; y < targetBitmap->GetHeight(); y++)
	{
		//get bytes rows from the original image
		byte* oRow = (byte*) pBmData->Scan0 + (y * pBmData->Stride );	

               //get byte rows  from the new image	
                byte* nRow = (byte*) bitmap_descriptor.bits32 + (y * bitmap_descriptor.lineStride32 * 4 ); 

		for (int x = 0; x < targetBitmap->GetWidth(); x++)
		{
			//set the new image's pixel to the grayscale version
			nRow[x * pixelSize]	   = oRow[x * pixelSize];       //B
			nRow[x * pixelSize + 1] = oRow[x * pixelSize + 1]; //G
			nRow[x * pixelSize + 2] = oRow[x * pixelSize + 2]; //R
		}
	}

	targetBitmap->UnlockBits( pBmData );
	_model->setEvfBitmap( NULL );
			
	// Free resources
	delete pBmData;
	delete targetBitmap;

	FREInvalidateBitmapDataRect( freBitmap, 0, 0, bitmap_descriptor.width,bitmap_descriptor.height );
        FREReleaseBitmapData( freBitmap );	

	FRENewObjectFromBool( 1, &result ); 
	return result;
}

To transfer the native bitmap to the bitmap passed by the runtime, the ANE try to do a byte per byte copy operation. That´s way is very important to have the same size ( width and height) in both sides.

Currently there is no support to the project but the code is published at: Github CanonEOS CPP

1 Comment

  1. Dev LFM May 5, 2016

    Hi,

    I’m trying to make it work, but I have no enough knowledge on c++

    If I understand, the timer on the AS3 swc no longer is required, and instead I have to listen to the “FREDispatchStatusEventAsync”. Is that right?

    Please help

Post a Reply

Your email address will not be published. Required fields are marked *