簡體   English   中英

如何在iOS中使用vImage旋轉和粘貼具有Alpha通道的圖像?

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

我有一個大圖像A和另一個圖像B,該圖像具有要粘貼到A中的Alpha通道。我想在將B貼上A之前對其進行仿射變換。在c ++中執行此步驟的步驟是什么在iOS中使用vImage?

我懷疑您是否可以在此處發布任何答案才能正常工作; 只是其中沒有足夠的細節來幫助遇到此類問題的人。

這是您的工作答案:

- (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 );

}

假設每個組件8位,則4通道數據:

  1. 取消預乘A-vImageUnpremultiplyData_ARGB8888
  2. 從B提取alpha通道-vImageExtractChannel_ARGB8888
  3. 變換B-vImageAffineWarp_Planar8
  4. 從A提取alpha通道-vImageExtractChannel_ARGB8888
  5. 將兩個Alpha通道相乘-vImagePremultiplyData_Planar8
  6. 將結果寫入A-vImageOverwriteChannels_ARGB8888
  7. 預乘A-vImagePremultiplyData_ARGB8888

如果您確實想用B代替A的alpha而不是將它們組合在一起,請跳過第4步和第5步。

如果在轉到下一條掃描線之前在一條掃描線上執行所有7個步驟,則整個過程將運行得更快。 kvImageDoNotTile和dispatch_apply()可用於相當簡單地對其進行多線程處理。

關於預倍增:您可以選擇是否對圖像進行預倍增。 通常會誇大預合成圖像的性能優勢。 將未預乘的圖像合成到預乘的曲面中,僅比將預乘的圖像合成要多得多。 預乘會導致大多數圖像濾鏡出現問題,從而導致一堆工作無法進行預乘並再次進行預乘。 這也會導致一些精度損失。 正如您在上面看到的,如果圖像沒有預乘,那么您要執行的操作將變得更加簡單。 只需第2步和第6步就可以很簡單,也可以單次使用vImageSelectChannels_ARGB8888 / vImagePermuteChannelsWithMaskedInsert_ARGB8888()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM