2015-01-25 5 views
0

큰 이미지 A와 A에 붙여 넣으려는 알파 채널이있는 다른 이미지 B가 있습니다. A에 붙이기 전에 B에 아핀 변환을 적용하고 싶습니다.이 작업을 수행하는 단계는 무엇입니까? iOS에서 vImage를 사용하는 C++?iOS에서 vImage를 사용하여 알파 채널로 이미지를 회전하고 붙여 넣을 수 있습니까?

+0

내가 여기에 세부 사항을 누락이 많을 후회. 이미지가 CGImageRefs입니까? vImage_Buffers? JPEG? UIImages? B.에 몇 개의 채널이 들어 있습니까? 이미 A에있는 알파를 덮어 쓰거나 혼합하려고합니까? 미리 곱셈 된가요? 낮은 수준의 그래픽 세부 사항에 익숙하지 않은 경우 가장 간단한 대답은 CGImageMask를 준비하고 CGImageRef에 첨부하는 것입니다. –

+0

vInage_buffers, 두 이미지 모두에 알파가 있고 미리 곱합니다. – twerdster

답변

1

나는 여기에 게시 된 답변 중 하나를 얻을 수 있었는지 의심 스럽습니다. 이 같은 질문을 가진 사람을 돕기에는 구체적인 내용이 충분하지 않습니다.

는 여기에 귀하의 작업 대답 :

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

}

0

성분마다 8 비트, 4 채널 데이터 가정 - B에서 vImageUnpremultiplyData_ARGB8888

  • 추출 알파 채널 -

    1. Unpremultiply는을 vImageAffineWarp_Planar8
    2. 추출물 알파 - vImageExtractChannel_ARGB8888
    3. 는 B 변환 채널로부터 - vImageExtractChannel_ARGB8888
    4. 2 개의 알파 채널을 함께 곱하십시오 - vImagePremultiplyData_Planar8
    5. 012 당신이 정말로, 함께 복합보다는 B와의 알파 교체 4 단계와 5 단계

      을 건너 뛰고 싶었다면 vImagePremultiplyData_ARGB8888

    - vImageOverwriteChannels_ARGB8888

  • 전치 승산의 A - 3,516,
  • 은에 결과를 쓰기

    한 스캔 라인에서 7 단계를 모두 수행하면 다음 스캔 라인으로 넘어 가기 전에 모든 것이 훨씬 빠르게 실행됩니다. kvImageDoNotTile 및 dispatch_apply()를 사용하면 상당히 간단하게 멀티 스레드 할 수 있습니다.

    미리 곱하기 : 이미지 이 미리 곱셈되어 있는지 여부를 선택할 수 있습니다. 미리 곱한 이미지 의 합성에 대한 성능 이점은 일반적으로 과장됩니다. 미리 곱셈되지 않은 이미지를 미리 곱셈 된 표면에 합성하는 것보다 조금 더 많은 것은 미리 곱한 것을 합성하는 것보다 더 많은 것입니다 ( ). 미리 곱하기는 대부분의 이미지 필터에 문제를 일으키며 결과적으로 다시 곱하기 및 다시 곱하기 작업을 수행하므로 결과적으로 이 발생합니다. 또한 은 정밀도를 약간 떨어 뜨립니다. 위에서 볼 수 있듯이, 이미지가 미리 곱하지 않은 인 경우, 원하는 작업은 훨씬 더 간단 해집니다. vImageSelectChannels_ARGB8888/vImagePermuteChannelsWithMaskedInsert_ARGB8888()을 사용하면 2 단계와 6 단계의 단순한 단계 일 수도 있고 단계의 단일 단계 일 수도 있습니다.