큰 이미지 A와 A에 붙여 넣으려는 알파 채널이있는 다른 이미지 B가 있습니다. A에 붙이기 전에 B에 아핀 변환을 적용하고 싶습니다.이 작업을 수행하는 단계는 무엇입니까? iOS에서 vImage를 사용하는 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 채널 데이터 가정 - B에서 vImageUnpremultiplyData_ARGB8888
- Unpremultiply는을 vImageAffineWarp_Planar8
- 추출물 알파 - vImageExtractChannel_ARGB8888
- 는 B 변환 채널로부터 - vImageExtractChannel_ARGB8888
- 2 개의 알파 채널을 함께 곱하십시오 - vImagePremultiplyData_Planar8 012 당신이 정말로, 함께 복합보다는 B와의 알파 교체 4 단계와 5 단계 을 건너 뛰고 싶었다면 vImagePremultiplyData_ARGB8888
- vImageOverwriteChannels_ARGB8888
한 스캔 라인에서 7 단계를 모두 수행하면 다음 스캔 라인으로 넘어 가기 전에 모든 것이 훨씬 빠르게 실행됩니다. kvImageDoNotTile 및 dispatch_apply()를 사용하면 상당히 간단하게 멀티 스레드 할 수 있습니다.
미리 곱하기 : 이미지 이 미리 곱셈되어 있는지 여부를 선택할 수 있습니다. 미리 곱한 이미지 의 합성에 대한 성능 이점은 일반적으로 과장됩니다. 미리 곱셈되지 않은 이미지를 미리 곱셈 된 표면에 합성하는 것보다 조금 더 많은 것은 미리 곱한 것을 합성하는 것보다 더 많은 것입니다 ( ). 미리 곱하기는 대부분의 이미지 필터에 문제를 일으키며 결과적으로 다시 곱하기 및 다시 곱하기 작업을 수행하므로 결과적으로 이 발생합니다. 또한 은 정밀도를 약간 떨어 뜨립니다. 위에서 볼 수 있듯이, 이미지가 미리 곱하지 않은 인 경우, 원하는 작업은 훨씬 더 간단 해집니다. vImageSelectChannels_ARGB8888/vImagePermuteChannelsWithMaskedInsert_ARGB8888()을 사용하면 2 단계와 6 단계의 단순한 단계 일 수도 있고 단계의 단일 단계 일 수도 있습니다.
내가 여기에 세부 사항을 누락이 많을 후회. 이미지가 CGImageRefs입니까? vImage_Buffers? JPEG? UIImages? B.에 몇 개의 채널이 들어 있습니까? 이미 A에있는 알파를 덮어 쓰거나 혼합하려고합니까? 미리 곱셈 된가요? 낮은 수준의 그래픽 세부 사항에 익숙하지 않은 경우 가장 간단한 대답은 CGImageMask를 준비하고 CGImageRef에 첨부하는 것입니다. –
vInage_buffers, 두 이미지 모두에 알파가 있고 미리 곱합니다. – twerdster