Log in or register to post comments

QCAR::Image to UIImage?

September 5, 2011 - 9:58am #1

Can anyone give me some pointers about creating a UIImage from QCAR::Image?
Thanks,
Fastas

QCAR::Image to UIImage?

July 15, 2015 - 3:41am #12

This has been extremely helpful, but on an iPhone 6 all we are getting is a series of grayscale frames of decreasing sizes and one YUV frame, which we can't decode.  Is there a way to provoke the phone into giving us a full colour image in a usable colour space?  Alternatively, are we going to have to interpret the YUV frame directly—and if so, is there documentation of the frame format somewhere?

QCAR::Image to UIImage?

April 12, 2015 - 6:03am #11

It should be noted that your code will crash if the qcarImage->getPixels() pointer becomes invalid. To return the image to the main thread you'll want to copy the underlying data first.

 

CGImageRef CGImageCreateWithQCARImage(const QCAR::Image *image)
{
    CGImageRef imageRef = NULL;

    if (image) {
        QCAR::PIXEL_FORMAT pixelFormat = image->getFormat();

        CGColorSpaceRef colorSpace = NULL;
        switch (pixelFormat) {
            case QCAR::RGB888:
                colorSpace = CGColorSpaceCreateDeviceRGB();
                break;
            case QCAR::GRAYSCALE:
                colorSpace = CGColorSpaceCreateDeviceGray();
                break;
            case QCAR::YUV:
            case QCAR::RGB565:
            case QCAR::RGBA8888:
            case QCAR::INDEXED:
                OARLogError("Image format conversion not implemented.");
                break;
            case QCAR::UNKNOWN_FORMAT:
                OARLogError("Image format unknown.");
                break;
        }

        if (colorSpace != NULL) {
            int bitsPerComponent = 8;
            int width = image->getWidth();
            int height = image->getHeight();
            const void *baseAddress = image->getPixels();
            size_t totalBytes = QCAR::getBufferSize(width, height, pixelFormat);

            CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone;
            CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

            int bitsPerPixel = QCAR::getBitsPerPixel(pixelFormat);
            int bytesPerRow = image->getStride();

            CFDataRef dataRef = CFDataCreate(NULL, (const UInt8 *)baseAddress, totalBytes);
            CGDataProviderRef provider = CGDataProviderCreateWithCFData(dataRef);

            imageRef = CGImageCreate(width,
                                     height,
                                     bitsPerComponent,
                                     bitsPerPixel,
                                     bytesPerRow,
                                     colorSpace,
                                     bitmapInfo,
                                     provider,
                                     NULL,
                                     false,
                                     renderingIntent);

            CGColorSpaceRelease(colorSpace);
            CGDataProviderRelease(provider);
            CFRelease(dataRef);
        }
    }
        
    return imageRef;
}

 

 

QCAR::Image to UIImage?

August 21, 2014 - 12:57am #10

Hey, 

I'm using exactly the same code.

Only issue is that i'm trying to use the UIImage in UIImageView i get weird crash 

it's something about __vConvert_RGB888toBGRA8888

 

I will try to be more specific

 

How to convert Image to UIImage and be able to load it into UIImageView ;)

 

Thanks!

QCAR::Image to UIImage?

August 16, 2012 - 2:46am #9

Hi abhishekkatare

This is to be expected, as this code is purely to get the video frame, not the augmentation.

Typically it is used as a method for integrating with another engine, which may need the video frame to use as a backdrop.

The augmentation must be handled separately as per the samples as shown in the render loop(s)

HTH

N

QCAR::Image to UIImage?

August 15, 2012 - 11:27pm #8

Hi Moderator,

I got UiImage through Your code ,

But the Problem is that I am not gettion 3D object in it .

 Could you please help,

Thanks 

Re: QCAR::Image to UIImage?

January 30, 2012 - 4:26am #7

It could be to do with when you are calling it. Can you let us know where you've put that call, and also put an NSLog("Setting frame format") trace by it and send us the debug log when it crashes, so we can see where in the lifecycle of QCAR it is called?

Re: QCAR::Image to UIImage?

January 30, 2012 - 4:07am #6

I have used the above screen capturing code in my app,but app is crashing at the line-
QCAR::setFrameFormat(QCAR::RGB888, true);

can anyone give me the reason?

Re: QCAR::Image to UIImage?

September 6, 2011 - 4:33am #5

[QUOTE=marchinram" />Can we not just use glReadPixels?[/QUOTE" />

It depends on what you are trying to do - if you look back, OdelWel asked how to create "a UIImage from QCAR::Image".

If you are allowing the rendering of the image to your EAGLView then you can alternatively use glReadPixels and choose to do so before or after the augmentation has been drawn. Apple provide the dos and donts here:

Technical Q&A QA1704
OpenGL ES View Snapshot
Q: How do I take a snapshot of my OpenGL ES view and save the result in a UIImage?

Re: QCAR::Image to UIImage?

September 6, 2011 - 4:06am #4

Can we not just use glReadPixels?

Re: QCAR::Image to UIImage?

September 6, 2011 - 12:08am #3

Perfect thank you!

Re: QCAR::Image to UIImage?

September 5, 2011 - 8:07pm #2

You'll want to start by registering for RGB888 images:

QCAR::setFrameFormat(QCAR::RGB888, true);

Then, in renderFrameQCAR (EAGLView.mm) you can get the QCAR image:

QCAR::Frame frame = state.getFrame();
for (int i = 0; i < frame.getNumImages(); i++)
{
    const QCAR::Image *qcarImage = frame.getImage(i);
    if (qcarImage->getFormat() == QCAR::RGB888)
    {
        UIImage *image = [self createUIImage:qcarImage];
    }
}

Here's one approach for getting a UIImage from the QCAR image:

void releasePixels(void *info, const void *data, size_t size)
{
    // do nothing
}

- (UIImage *)createUIImage:(const QCAR::Image *)qcarImage
{
    int width = qcarImage->getWidth();
    int height = qcarImage->getHeight();
    int bitsPerComponent = 8;
    int bitsPerPixel = QCAR::getBitsPerPixel(QCAR::RGB888);
    int bytesPerRow = qcarImage->getBufferWidth() * bitsPerPixel / bitsPerComponent;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, qcarImage->getPixels(), QCAR::getBufferSize(width, height, QCAR::RGB888), releasePixels);
    
    CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
    UIImage *image = [[UIImage imageWithCGImage:imageRef] retain];
    
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpaceRef);
    CGImageRelease(imageRef);
    
    return image;
}

Finally, note that you cannot update the UI directly from the renderFrameQCAR method, as this is called on the GL thread. Use the performSelectorOnMainThread method if you want to use this image to say update an image view.

- Kim

Log in or register to post comments