Log in or register to post comments

Vuforia SDK: how to take screenshots?

November 8, 2012 - 10:50am #1

I realize this has been covered many times on this forum, but I can only get this working on a 5.0 device and not a 6.0 device. Not sure what the issue is!

The closest I've gotten it to working is by using the code found in this thread:

https://ar.qualcomm.at/content/take-screenshot

In fact, it works every time on my 5.0 device, but never works on my 6.0 device.

Any clues?

Vuforia SDK: how to take screenshots?

January 6, 2014 - 2:57am #28

What is the problem with the source code I posted below?

N

Vuforia SDK: how to take screenshots?

January 3, 2014 - 7:44am #27

Hi NalinS

Thanks you for help. I have take image 3d model but i want to capture image with object overlay like sample books cloud in vuforiasamples when move ipad moving away trackable.

Help me.

Thanks

Vuforia SDK: how to take screenshots?

August 1, 2013 - 9:45am #26

Well, since then, the code has morphed into

     GLint backingWidth, backingHeight;

     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);

     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);    

     CGRect s = CGRectMake(0, 0, backingWidth, backingHeight);

 

so would I simply swap backingWidth and backingHeight?

I'll try that, but I also found another solution, which is to use a category for UIImage to rotate the image 90 degrees

http://www.catamount.com/forums/viewtopic.php?f=21&t=967

Thanks!

Vuforia SDK: how to take screenshots?

August 1, 2013 - 9:18am #25

Well, it's a big thread....

but  I think this was the code that worked.

 

Consequently, I was able to take a full screenshot by exchanging with and height values:

/*

    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"])

        s = CGRectMake(0, 0, 768.0f * scale, (1024.0f) * scale);

    else

        s = CGRectMake(0, 0, 320.0f * scale, (480.0f) * scale);

*/

    if ([[[UIDevice currentDevicemodelisEqualToString:@"iPad"])

        s = CGRectMake(00, (1024.0f) * scale, 768.0f * scale);

    else

        s = CGRectMake(00, (480.0f) * scale, 320.0f * scale);

 

 

...so you'll probably have to experiment, but everything you need should be below.

 

N

 

 

 

Vuforia SDK: how to take screenshots?

August 1, 2013 - 7:34am #24

Hi Nalin,

This code works great.  Only issue, which I think was discussed below, is that it appears to be rotated 90 degrees when saved to the camera role.  Is there code in glToUIImage which explictly does the rotation that I can change?

 

Vuforia SDK: how to take screenshots?

May 9, 2013 - 12:49am #23

Hi Nalin,

Thank you very much for this help. I am only replace the code of  -(UIImage *)glToUImage to your code.

 

 

 

Vuforia SDK: how to take screenshots?

May 7, 2013 - 7:34am #22

I found I was able to takle screenshots in both portrait and landscape mode by adding the code below to AR_EAGLView.mm.  Moreover this takes the width and height parameters from openGL ES.

In my particular case I added a test in presentFrameBuffer to check a BOOL that is set by a UIButton from outside, and reset inside.  This may help to avoid any threading issues as the rendering is done on a background thread.

HTH

N

 

 

- (BOOL)presentFramebuffer

{

    if (takePhoto)

    {

        [self glToUIImage];

        takePhoto = NO;

    }

 
....remaining code ...

}

 

 

 

- (UIImage*) glToUIImage

 

{

    GLint backingWidth, backingHeight;

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

    

    CGRect s = CGRectMake(0, 0, backingWidth, backingHeight);

    

    uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);

    glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);

    CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, CGColorSpaceCreateDeviceRGB(),

                                    kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);

            

    size_t width = CGImageGetWidth(iref);

    size_t height = CGImageGetHeight(iref);

    size_t length = width * height * 4;

    uint32_t *pixels = (uint32_t *)malloc(length);

    

    CGContextRef cgcontext = CGBitmapContextCreate(pixels, width, height, 8, width * 4,

                                                 CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);

    

    CGAffineTransform transform = CGAffineTransformIdentity;

    transform = CGAffineTransformMakeTranslation(0.0f, height);

    transform = CGAffineTransformScale(transform, 1.0, -1.0);

    CGContextConcatCTM(cgcontext, transform);

    CGContextDrawImage(cgcontext, CGRectMake(0.0f, 0.0f, width, height), iref);

    CGImageRef outputRef = CGBitmapContextCreateImage(cgcontext);

    

    UIImage* outputImage = [UIImage imageWithCGImage:outputRef];

    UIImageWriteToSavedPhotosAlbum(outputImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

    

    CGDataProviderRelease(ref);

    CGImageRelease(iref);

    CGContextRelease(cgcontext);

    CGImageRelease(outputRef);

    

    free(pixels);

    free(buffer);

    

    NSLog(@"Screenshot size: %d, %d", (int)[outputImage size].width, (int)[outputImage size].height);

    

    return outputImage;

}

 

 

// callback for UIImageWriteToSavedPhotosAlbum

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {

    

    if (error) {

        NSLog(@"Photo save error");

    }

    else {

        NSLog(@"Photo saved");

    }

}

 

 

Vuforia SDK: how to take screenshots?

May 7, 2013 - 6:01am #21

@khushi, did you see my earlier post?

I'm not sure, because that was some time ago, but I think that I had similar problem and my solution worked.

Vuforia SDK: how to take screenshots?

May 7, 2013 - 5:14am #20

 

The black screen you are talking about might be from the glReadPixels method from OpenGL. Try pausing the video (if its playing) before you "take photo" as the glReadPixel does not use the camera but reads all the pixels from you screen and transforms them in an image.

This is the method I used, it's slightly different:

+ (UIImage*)glToUIImageWithOrientation:(UIInterfaceOrientation)orientation 

{

    CGFloat scale = [[UIScreen mainScreen] scale];

    CGRect s;

    

    s = CGRectMake(0, 0, frame.size.height * scale, frame.size.width * scale);

    

    uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);

 

    glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

    CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, colorSpaceRef,

                                    kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);

    CGColorSpaceRelease(colorSpaceRef);

    size_t width = CGImageGetWidth(iref);

    size_t height = CGImageGetHeight(iref);

    size_t length = width * height * 4;

    uint32_t *pixels = (uint32_t *)malloc(length);

    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * 4,

                                                 CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);

    

    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);

    CGImageRef outputRef = CGBitmapContextCreateImage(context);

    UIImage *outputImage = nil;

    if (orientation == UIInterfaceOrientationLandscapeLeft) {

        outputImage = [[UIImage alloc]initWithCGImage:outputRef scale:(CGFloat)1.0 orientation:UIInterfaceOrientationLandscapeLeft];

    } else if (orientation == UIInterfaceOrientationPortrait){

        outputImage = [[UIImage alloc] initWithCGImage:outputRef scale:(CGFloat)1.0 orientation:UIImageOrientationLeftMirrored];

    } else if (orientation == UIInterfaceOrientationLandscapeRight) {

        outputImage = [[UIImage alloc]initWithCGImage:outputRef scale:(CGFloat)1.0 orientation:UIInterfaceOrientationPortrait];

    } else {

        outputImage = [[UIImage alloc]initWithCGImage:outputRef scale:(CGFloat)1.0 orientation:orientation];

    }

    

    CGDataProviderRelease(ref);

    CGImageRelease(iref);

    CGContextRelease(context);

    CGImageRelease(outputRef);

    

    free(pixels);

    free(buffer);

    

    return outputImage;

}

Vuforia SDK: how to take screenshots?

May 7, 2013 - 5:00am #19

Unfortunately there is no magic solution - you need to debug your code.

Just because it worked for somebody else does not mean that the code will automatically work for you, especially since you have changed the code so significantly..

I suggest you start with the Apple guidelines on how to take a screenshot:

Technical Q&A QA1704: Technical Q&A QA1704

http://developer.apple.com/library/ios/#qa/qa1703/_index.html

 

If you persist with trying to make the code in the post work, you will need to debug it.

Looking at it briefly, not sure why you are doing this:

 NSInteger myDataLength = 320 * 480 * 8;//4

...as it is only 4 bytes per pixel, not 8, and why you have changed the code?

Also, you need to be clearer with your explanations.  Saying you have a half a black screen is meaningless without saying what you have changed and why, along with what you have tried to get it to work.

 

N

 

 

 

 

Vuforia SDK: how to take screenshots?

May 6, 2013 - 2:45am #18

Hi,

 

I got a half black screen on my album, When i take screenShot.

 

I written  following code below :-

 

@interface VBOverlayViewController : OverlayViewController {

 

 

 UIButton *takePhoto;

}

 

@property (nonatomic,assign)UIButton *takePhoto;

//For Take a screen Shot

-(UIImage *)glToUIImage;

-(void)TakePhoto;

 

 

 

 

@implementation VBOverlayViewController

@synthesize takePhoto;

 

-(void)loadView

{

 

 

   takePhoto = [[UIButton alloc]initWithFrame:CGRectMake(0, 14, 70, 70)];

//    takePhoto.backgroundColor = [UIColor colorWithPatternImage:[]];

    [takePhoto setTitle:@"Take Photo" forState:UIControlStateNormal];

    [takePhoto.titleLabel setFont:[UIFont systemFontOfSize:12.0]];

    [takePhoto addTarget:self action:@selector(TakePhoto) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:takePhoto];

 

}

 

 

-(UIImage *)glToUIImage

{

    NSInteger myDataLength = 320 * 480 * 8;//4

    

    //allocate array and read pixels into it.

    GLubyte *buffer = (GLubyte *)malloc(myDataLength);

    glReadPixels(0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    

    //gl renders "upside down" so swap top bottom into new array.

    //there's gotta be a better way, but this works.

    

    GLubyte *buffer2 = (GLubyte *)malloc(myDataLength);

    for(int y = 0; y<480; y++)

    {

        for (int x=0; x<320; x++) {

            

            buffer2[(479 - y) * 320 * 4 + x] = buffer[y * 4 * 320 + x];//4

        }

    }

    

    //make data provider with data.

    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);

    

    //prep the ingredients

    int bitsPerComponent = 8;//8

    int bitPerPixel = 32;//64

    int bytePerRow = 4 * 320;//4

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;

    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    

    //make the cgimage

    CGImageRef imageRef = CGImageCreate(320, 480, bitsPerComponent, bitPerPixel, bytePerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    

    NSLog(@"imageRef:-%@",imageRef);

    

    //then make the uiImage from that

    UIImage *myImage = [UIImage imageWithCGImage:imageRef];

    NSLog(@"myImage:-%@",myImage);

    return myImage;

        

}

 

 

 

-(void)TakePhoto

{

    UIImage *image = [self glToUIImage];

    NSLog(@"imge:-%@",image);

    

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Get It!" message:@"Go to the Album." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

    [alert show];

    

    UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);

    

    

}

 
//EaglView.m-------------
 

@implementation EAGLView

 

- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    

if (self)

    {

        

        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

        

        eaglLayer.opaque = TRUE;

        //        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

        //                                        [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,

        //                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,

        //                                        nil];

        

        

        eaglLayer.drawableProperties = @{

        

    kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES],

        

    kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8,

        

        };

 

 

What I do, because I m doing all codes.Please guide me.

Thank you

Khushi

Vuforia SDK: how to take screenshots?

March 26, 2013 - 4:11am #17

Great to hear :)

N

Vuforia SDK: how to take screenshots?

March 26, 2013 - 3:43am #16

Hi!

It seems to be a problem from how I was saving the photo in Camera. Fixed it.

Thanks anyway!

Vuforia SDK: how to take screenshots?

March 26, 2013 - 3:33am #15

I cannot remember exactly as it was four months ago...

However, reading the thread below it had something to do with this:

 

When I built an app with your screen shot code from the forums I got a black screen, however when I added these lines I got an image:
 
        eaglLayer.drawableProperties = @{
 
                                         kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES],
 
                                         kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8,
 
        };
 
 
 
I replaced the previous eaglLayer initialisation with above.
 
I got an image on iPhone 4S and 5. 

 

If this is not working for you try searching the code for "screenshot", as I also recently posted very similar code elsewhere that saved to the photo album.

 

HTH

N

Vuforia SDK: how to take screenshots?

March 25, 2013 - 3:06pm #14

You said in a comment:

 

"Hi jacksmash,

When I run your sample it crashes in main()

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([ImageTargetsAppDelegate class]));"

 

How did you solve this?

Vuforia SDK: how to take screenshots?

March 25, 2013 - 9:46am #13

I have no idea about the crash you are talking about...

N

Vuforia SDK: how to take screenshots?

March 25, 2013 - 9:14am #12

Hi NalinS,

Does this solve the crash from 

return UIApplicationMain(argc, argv, nil, NSStringFromClass([ImageTargetsAppDelegate class]));?

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSInvocation setArgument:atIndex:]: index (4) out of bounds [-1, 3]'

I get that same error too, but I can't get rid of it.

 

Thanks in advance!

Thanks for this. I should

January 17, 2013 - 5:12am #11

Thanks for this. I should have posted a long time ago when I solved this. My solution is analogous to yours. I essentially employ the delegate design pattern, where my EAGL view tells me when I'm allowed to take a screenshot, and that's when I take it (assuming the user has pressed the button to take a screenshot, of course).

Thanks for sharing! N

January 17, 2013 - 2:38am #10

Thanks for sharing!

N

 First of all, thanks for

January 17, 2013 - 2:33am #9

First of all, thanks for Your code, jacksmash - it works for me (in iOS 6 afrer NalinS corrections).

I had problem with random black lines on screenshot also. I implemented something like simples semaphores and there is no black lines for me. :)

 

//global variables, top of EAGLView.h

BOOL render = NO;
BOOL screenshoot = NO;

...

- (void)renderFrameQCAR
{
    if(screenshoot)

         return;

    render = YES;

    [self setFramebuffer];

//rest of code

   render = NO;

}

-(IBAction)takeScreenshot:(id)sender

{

    while(render)

    {

    }

    screenshoot = YES;

    //code for taking screenshot

    screenshoot = NO;

}

 

 

Vuforia SDK: how to take screenshots?

November 22, 2012 - 5:38am #8

Many thanks for the feedback! Although I'm a bit embarrassed that I didn't see that... Embarassed

I'm including the updated code below. This takes the screenshot and rotates it correctly so that it can be viewed within a UIImageView. I'm still getting lines of black pixels though. I must not be flushing the render buffer properly... any thoughts on that?

Here's the updated code:

 

- (UIImage*) glToUIImage

{

    CGFloat scale = [[UIScreen mainScreen] scale];

    CGRect s;

    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"])

        s = CGRectMake(0, 0, 1024.0f * scale, (768.0f) * scale);

    else

        s = CGRectMake(0, 0, 480.0f * scale, (320.0f) * scale);

    uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);

    glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);

    CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, CGColorSpaceCreateDeviceRGB(),

                                    kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);

    size_t width = CGImageGetWidth(iref);

    size_t height = CGImageGetHeight(iref);

    size_t length = width * height * 4;

    uint32_t *pixels = (uint32_t *)malloc(length);

    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * 4,

                                                 CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);

    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);

    CGImageRef outputRef = CGBitmapContextCreateImage(context);

    UIImage* outputImage = [[UIImage alloc] initWithCGImage:outputRef scale:(CGFloat)1.0 orientation:UIImageOrientationLeftMirrored];

    CGDataProviderRelease(ref);

    CGImageRelease(iref);

    CGContextRelease(context);

    CGImageRelease(outputRef);

    free(pixels);

    free(buffer);  

    NSLog(@"Screenshot size: %d, %d", (int)[outputImage size].width, (int)[outputImage size].height);

    return outputImage;

}

Vuforia SDK: how to take screenshots?

November 22, 2012 - 3:54am #7

Hi jacksmash,

I talked with one of the iOS developers and he explained that the problem is because you are using using a portrait rectangle to read the pixels out of a landscape GL buffer.  Vuforia uses landscape by default and then rotates accordingly with the various transformations.

Consequently, I was able to take a full screenshot by exchanging with and height values:

/*

    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"])

        s = CGRectMake(0, 0, 768.0f * scale, (1024.0f) * scale);

    else

        s = CGRectMake(0, 0, 320.0f * scale, (480.0f) * scale);

*/

    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"])

        s = CGRectMake(0, 0, (1024.0f) * scale, 768.0f * scale);

    else

        s = CGRectMake(0, 0, (480.0f) * scale, 320.0f * scale);

 

Hope you can find your way round the black screen problem, as I did, so this can work for you.

N

Vuforia SDK: how to take screenshots?

November 21, 2012 - 6:38am #6

Hi jacksmash,

When I run your sample it crashes in main()

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([ImageTargetsAppDelegate class]));

When I built an app with your screen shot code from the forums I got a black screen, however when I added these lines I got an image:

        eaglLayer.drawableProperties = @{

                                         kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES],

                                         kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8,

        };

 

I replaced the previous eaglLayer initialisation with above.

I got an image on iPhone 4S and 5. 

However as you say the image is rotated, but also the actual image is square, so not sure whether it has been rotated too soon or that something else is out of order here as I am not that familiar with the screenshot code.

I think you might need to look at your screenshot code, and maybe try it outside a Vuforia app to make sure it works in different circumstances.

Here are a few other links you might find useful:

https://developer.apple.com/library/ios/#qa/qa1714/_index.html

http://developer.apple.com/library/ios/#qa/qa1704/_index.html

http://brokenfang.com/2012/07/14/how-to-legally-replace-uigetscreenimage/

 

HTH

N

 

Vuforia SDK: how to take screenshots?

November 20, 2012 - 5:14am #5

I'm going to try to describe this a little more succinctly.

1. I downloaded and ran the sample Vuforia SDK (ImageTargets) project as found in the samples directory.

2. In the ARParentViewController.mm class, I added the glToUiImage function exactly as shown in my previous post in this thread.

3. In the viewDidLoad function of the ARParentViewController class, I added a UIButton. When that button is pressed, the following code is executed:

 

- (void) takeScreenshot

{

    UIImage *screenshotImage = [self glToUIImage];

    ScreenshotViewController *pictureView;

    pictureView = [[ScreenshotViewController alloc] initWithNibName:@"ScreenshotViewController" bundle:nil];

    [pictureView setScreenshotImage:screenshotImage];

    [self presentModalViewController:pictureView animated:YES];

}

 

The ScreenshotViewController is quite simple. It diplays a UIImageView and has a property of type UIImage that gets set before the view controller is shown modally.

4. Now, based on another thread in this forum, I updated the the initWithFrame function in the AR_EAGLView class to contain this line:

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

                                        [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,

                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,

                                        nil];

5. The bottom line is that there are two problems when the user pressed the camera button (as described in step 3 above).

PROBLEM 1: The screenshot is rotated 90 degrees in the UIImageView on the ScreenshotViewController.

PROBLEM 2: The screenshot is not always complete (sometimes it is all black, but most often some pixels are black while others show the correct details).

Thanks for reading. Please ask questions if anything needs to be clarified.

 

Vuforia SDK: how to take screenshots?

November 12, 2012 - 1:59am #4

Ok, thanks for sharing.

I will try to look at this some more in due course.

N

Vuforia SDK: how to take screenshots?

November 9, 2012 - 1:13pm #3

Ok, so here's the code that is working, except the image result is rotated: 

- (UIImage*) glToUIImage

{

    CGFloat scale = [[UIScreen mainScreen] scale];

    CGRect s;

    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"])

        s = CGRectMake(0, 0, 768.0f * scale, (1024.0f) * scale);

    else

        s = CGRectMake(0, 0, 320.0f * scale, (480.0f) * scale);

    

    uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);

    

    glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);

    

    CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, CGColorSpaceCreateDeviceRGB(),

                                    kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);

    

    size_t width = CGImageGetWidth(iref);

    size_t height = CGImageGetHeight(iref);

    size_t length = width * height * 4;

    uint32_t *pixels = (uint32_t *)malloc(length);

    

    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * 4,

                                                 CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);

//    CGContextRotateCTM (context, radians(90));

    

    CGAffineTransform transform = CGAffineTransformIdentity;

    transform = CGAffineTransformMakeTranslation(0.0f, height);

    transform = CGAffineTransformScale(transform, 1.0, -1.0);

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);

    CGImageRef outputRef = CGBitmapContextCreateImage(context);

    

    UIImage* outputImage = [UIImage imageWithCGImage:outputRef];//] scale:1.0f orientation:UIImageOrientationRight];

//    UIImageWriteToSavedPhotosAlbum(outputImage, self, nil, nil);

    

//    [outputImage r]

    

    CGDataProviderRelease(ref);

    CGImageRelease(iref);

    CGContextRelease(context);

    CGImageRelease(outputRef);

    free(pixels);

    free(buffer);

    

    NSLog(@"Screenshot size: %d, %d", (int)[outputImage size].width, (int)[outputImage size].height);

 

    return outputImage;

}

 

Vuforia SDK: how to take screenshots?

November 9, 2012 - 7:31am #2

Ok, I've kinda got this working following the advice in this thread:

https://ar.qualcomm.at/content/texture2dreadpixels-not-working-ios6

I have the code below in the ARParentViewController class. Problem is, it captures the pixels in landscape even though my app is in portrait mode. I'm a little puzzled by this. Bottom line is that when I assign the UIImage to a UIImageView, the screenshot is rotated 90-degrees.

Thoughts?

Edit: I can't paste the code for some reason. I'll add it once I figure out how.

Log in or register to post comments