I'm making an experiment with a native extension to access device camera on iOS. The goal is make a stream of a UIView on a BitmapData on AS3.
mView=[[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:mSession];
previewLayer.frame = mView.bounds;
[mView.layer addSublayer:previewLayer];
That's the part of the code where add a sub layer with the camera preview on the UIView, then, in the ANE Controller:
FREObject drawViewToBitmap(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { // grab the AS3 bitmapData object for writing to FREBitmapData bmd; int32_t _id;
//get CCapture object that contains the camera interface...
CCapture* cap;
FREGetObjectAsInt32(argv[0], &_id);
cap = active_cams[_id];
//When start's to capture
if(cap && captureCheckNewFrame(cap))
{
UIView* myView = getView(cap); //<--- Here I get the mView from the code above
FREAcquireBitmapData(argv[1], &bmd);
// Draw the UIView to a UIImage object. myView is a UIView object
// that exists somewhere in our code. It can be any view.
UIGraphicsBeginImageContext(myView.bounds.size);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Now we'll pull the raw pixels values out of the image data
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Pixel color values will be written here
unsigned char *rawData = (unsigned char*)malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Pixels are now in rawData in the format RGBA8888
// We'll now loop over each pixel write them into the AS3 bitmapData memory
int x, y;
// There may be extra pixels in each row due to the value of
// bmd.lineStride32, we'll skip over those as needed
int offset = bmd.lineStride32 - bmd.width;
int offset2 = bytesPerRow - bmd.width*4;
int byteIndex = 0;
uint32_t *bmdPixels = bmd.bits32;
// NOTE: In this example we are assuming that our AS3 bitmapData and our
// native UIView are the same dimensions to keep things simple.
for(y=0; y<bmd.height; y++) {
for(x=0; x<bmd.width; x++, bmdPixels ++, byteIndex += 4) {
// Values are currently in RGBA8888, so each colour
// value is currently a separate number
int red = (rawData[byteIndex]);
int green = (rawData[byteIndex + 1]);
int blue = (rawData[byteIndex + 2]);
int alpha = (rawData[byteIndex + 3]);
// Combine values into ARGB32
* bmdPixels = (alpha << 24) | (red << 16) | (green << 8) | blue;
}
bmdPixels += offset;
byteIndex += offset2;
}
// free the the memory we allocated
free(rawData);
// Tell Flash which region of the bitmapData changes (all of it here)
FREInvalidateBitmapDataRect(argv[0], 0, 0, bmd.width, bmd.height);
// Release our control over the bitmapData
FREReleaseBitmapData(argv[0]);
}
return NULL;
The problem is on this line: image = UIGraphicsGetImageFromCurrentImageContext();, image is with width/height = 0 and the rest of the code fails in the line "int red = (rawData[byteIndex]);", anyone knows where can be the problem?
The function drawViewToBitmap it's a code from Tyler Egeto that I trying to use with an ANE from github/inspirit to stream an UIView screen sized instead of the big Still Image that is a lot expensive to resize in AS3 side.
Thank's!