Search code examples
c++iosaffinetransformaccelerate-frameworkvimage

How can I rotate and paste image with alpha channel using vImage in ios?


I have a large image A and another image B which has an alpha channel that I would like to paste into A. I want to apply an affine transform to B before I stick it on to A. What are the steps to doing this in c++ using vImage in iOS?


Solution

  • I doubt you were able to get any of the answers posted here to work; there are just not enough specifics in them to help someone who had a question like this to begin with.

    Here's your working answer:

    - (CVPixelBufferRef)copyRenderedPixelBuffer:(CVPixelBufferRef)pixelBuffer {
    
    CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
    
    unsigned char *base = (unsigned char *)CVPixelBufferGetBaseAddress( pixelBuffer );
    size_t width = CVPixelBufferGetWidth( pixelBuffer );
    size_t height = CVPixelBufferGetHeight( pixelBuffer );
    size_t stride = CVPixelBufferGetBytesPerRow( pixelBuffer );
    //size_t extendedWidth = stride / sizeof( uint32_t ); // each pixel is 4 bytes/32 bits
    vImage_Buffer _img = {
        .data = base,
        .height = height,
        .width = width,
        .rowBytes = stride
    };
    
    size_t pixelBufferSize = (stride  * height) / sizeof(uint8_t);
    void* gBuffer = malloc(pixelBufferSize);
    vImage_Buffer _dstG = {
        .data = gBuffer,
        .height = height / sizeof(uint8_t),
        .width = width / sizeof(uint8_t),
        .rowBytes = stride / sizeof(uint8_t)
    };
    
    vImage_Error err;
    
    const uint8_t map[4] = { 3, 2, 1, 0 };
    err = vImagePermuteChannels_ARGB8888(&_img, &_img, map, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"Error: %ld", err);
    
    err = vImageExtractChannel_ARGB8888(&_img, &_dstG, 2, kvImageNoError);
    if (err != kvImageNoError)
        NSLog(@"Error: %ld", err);
    
    err = vImageEqualization_Planar8(&_dstG, &_dstG, kvImageNoError);
    if (err != kvImageNoError)
        NSLog(@"Error: %ld", err);
    
    err = vImageContrastStretch_Planar8( &_dstG, &_dstG, kvImageNoError );
    if (err != kvImageNoError)
        NSLog(@"Error: %ld", err);
    
    err = vImageOverwriteChannels_ARGB8888(&_dstG, &_img, &_img, 0x2, kvImageNoError);
    if (err != kvImageNoError)
        NSLog(@"Error: %ld", err);
    
    err = vImagePermuteChannels_ARGB8888(&_img, &_img, map, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"Error: %ld", err);
    
    CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
    
    free(gBuffer);
    
    return (CVPixelBufferRef)CFRetain( pixelBuffer );
    

    }