2014-05-12 20 views
9

Potrzebuję wyciąć z pełnego obrazu za pomocą maski i utworzyłem zamaskowany obraz.Jak zaimplementować GPUImageMaskFilter za pomocą GPUImage

Full Image+Mask Image=enter image description here

Próbowałem następujące:

UIImage *imgMask = [UIImage imageNamed:@"Mask.png"]; 
UIImage *imgBgImage = [UIImage imageNamed:@"Full.png"]; 



GPUImageMaskFilter *maskingFilter = [[GPUImageMaskFilter alloc] init]; 


GPUImagePicture * maskGpuImage = [[GPUImagePicture alloc] initWithImage:imgMask ]; 

GPUImagePicture *FullGpuImage = [[GPUImagePicture alloc] initWithImage:imgBgImage ]; 




[maskGpuImage addTarget:maskingFilter]; 
[maskGpuImage processImage]; 


[maskingFilter useNextFrameForImageCapture]; 


[FullGpuImage addTarget:maskingFilter]; 
[FullGpuImage processImage]; 



UIImage *OutputImage = [maskingFilter imageFromCurrentFramebuffer]; 

Ale, mój wyjściowy generowany obraz jest: enter image description here

Proszę faceci się za ręce. Pozdrawiam.

Ponadto, dzięki BradLarson.

+0

Dobre pytanie. Mam podobne zadanie i teraz próbuję go rozwiązać dwoma obrazami - jednym dla maski i drugim dla wiązania. – Avt

+0

To naprawdę niepokojący obraz wyjściowy. – niksawtschuk

+0

Jako pierwszy krok, spróbuj zamienić wskaźniki tekstury w następujący sposób: '[FullGpuImage addTarget: maskingFilter atIndex: 0];' '[maskGpuImage addTarget: maskingFilter atIndex: 1];' Sprawdź, czy to zbliża cię do pożądanego wyniku. – Jack

Odpowiedz

2

Nie potrzebujesz filtra maski, ale mieszankę alfa.

I wdrożone jeden here tak:

// GPUImage shader strings 
NSString * const kNBUAlphaMaskShaderString = SHADER_STRING 
(
varying highp vec2 textureCoordinate; 
varying highp vec2 textureCoordinate2; 

uniform sampler2D inputImageTexture; 
uniform sampler2D inputImageTexture2; 

void main() 
{ 
    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); 
    lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); 

    gl_FragColor = vec4(textureColor.xyz, textureColor2.a); 
} 
); 

prostu zachowuje kolory z jednego obrazu i kanał alfa drugiego.

Następnie createGPUImageTwoInputFilter:

GPUImageTwoInputFilter * alphaMask = [[GPUImageTwoInputFilter alloc] initWithFragmentShaderFromString:kNBUAlphaMaskShaderString]; 

Nie jestem pewien, czy podobny filtr mieszanka został dodany do GPUImage od.


Wystarczy ponownie sprawdzić, czy jest wbudowana mieszanka, która to robi, a nie ma. Ale filtr mieszania, którego użyłem jako inspiracji, nadal tam jest (GPUImageAlphaBlendFilter). Łączy dwa obrazy za pomocą maski alfa, aby je miksować. Wymieniony filtr nie wymaga drugiego "pustego" obrazu.

+0

Thx. Pozwól mi też spróbować tego. – itechnician

5

Maska jest celem sekund, jak można zobaczyć w kodzie modułu cieniującego filtru (textureColor2).

//Averages mask's the RGB values, and scales that value by the mask's alpha 
// 
//The dot product should take fewer cycles than doing an average normally 
// 
//Typical/ideal case, R,G, and B will be the same, and Alpha will be 1.0 

lowp float newAlpha = dot(textureColor2.rgb, vec3(.33333334, .33333334, .33333334)) * textureColor2.a; 

gl_FragColor = vec4(textureColor.xyz, newAlpha); 

Następnie trzeba „odwracać” maskę: białe serca na czarnym tle, jak filtr wykorzystuje „wagę” wartości RGB piksela, aby ustawić wartość alfa na obrazie docelowym.

więc kod powinien być

// Image first, Mask next 
[FullGpuImage addTarget:maskingFilter]; 
[FullGpuImage processImage]; 

[maskingFilter useNextFrameForImageCapture]; 

[maskGpuImage addTarget:maskingFilter]; 
[maskGpuImage processImage];  

i maska ​​(ok zrobiłem brzydki szybki test, należy użyć właściwego obrazu) jak

white heart on black background

do oczekiwanego rezultatu.

masked image

+0

Dzięki, pozwól mi spróbować. – itechnician