使用GPUImage我试图用不透明度复制Photoshop Lighten Blend Mode。 不幸的是,alpha通道使用GPUImageLightenBlendFilter没有任何效果。
Brad确认alpha可能存在问题: GPUImage的GPUImageOpacityFilter表现不正常,不会改变alpha通道
我已成功使用CoreImage复制了PS混合,后者尊重alpha值。
CIImage *ciImage1 = [[CIImage alloc] initWithImage:input1]; CIImage *ciImage2 = [[CIImage alloc] initWithImage:input2]; // Alpha adjustment for input1 CIFilter *alphaFilter = [CIFilter filterWithName:@"CIColorMatrix"]; CGFloat rgba[4] = { 0.0, 0.0, 0.0, 0.5 }; CIVector *alphaVector = [CIVector vectorWithValues:rgba count:4]; [alphaFilter setValue:alphaVector forKey:@"inputAVector"]; [alphaFilter setValue:ciImage1 forKey:kCIInputImageKey]; // Lighten blend CIFilter *blendFilter = [CIFilter filterWithName:@"CILightenBlendMode"]; [blendFilter setValue:alphaFilter.outputImage forKey:kCIInputImageKey]; [blendFilter setValue:ciImage2 forKey:kCIInputBackgroundImageKey];我尝试过2个版本的GPUImage (他们使用不同的方法调整input1 alpha值)。
GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageOpacityFilter *alphaFilter = [GPUImageOpacityFilter new]; alphaFilter.opacity = 0.5; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];要么:
GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageColorMatrixFilter *alphaFilter = [GPUImageColorMatrixFilter new]; alphaFilter.colorMatrix = (GPUMatrix4x4) { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.5 } }; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];两个GPUImage实现都返回输出,就像input1 alpha为1.0 。
我在互联网上查看了不同来源的Lighten Blending Mode文档,他们都使用这个公式:
max(blend, base)在实现GPUImageLightenBlendFilter着色器,它也使用相同的公式:
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); gl_FragColor = max(textureColor, textureColor2);但是,似乎Photoshop和CoreImage对alpha有一些额外的操作(可能类似于Gimp: https : //github.com/GNOME/gimp/blob/783bbab8a889d4eba80b6a83f2e529937a73a471/app/operations/gimpoperationlightenonlymode.c )。
任何人都有想法如何在GPUImageLightenBlendFilter公式中包含alpha通道?
Using GPUImage I am trying to replicate Photoshop Lighten Blend Mode with opacity. Unfortunately the alpha channel has no effect using the GPUImageLightenBlendFilter.
Brad confirms there might problems with alpha: GPUImage's GPUImageOpacityFilter not behaving as expected, doesn't change alpha channel
I have successfully replicated the PS blending using CoreImage which respects the alpha value.
CIImage *ciImage1 = [[CIImage alloc] initWithImage:input1]; CIImage *ciImage2 = [[CIImage alloc] initWithImage:input2]; // Alpha adjustment for input1 CIFilter *alphaFilter = [CIFilter filterWithName:@"CIColorMatrix"]; CGFloat rgba[4] = { 0.0, 0.0, 0.0, 0.5 }; CIVector *alphaVector = [CIVector vectorWithValues:rgba count:4]; [alphaFilter setValue:alphaVector forKey:@"inputAVector"]; [alphaFilter setValue:ciImage1 forKey:kCIInputImageKey]; // Lighten blend CIFilter *blendFilter = [CIFilter filterWithName:@"CILightenBlendMode"]; [blendFilter setValue:alphaFilter.outputImage forKey:kCIInputImageKey]; [blendFilter setValue:ciImage2 forKey:kCIInputBackgroundImageKey];There are 2 versions of GPUImage I have tried (they are adjusting alpha for input1 using a different method).
GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageOpacityFilter *alphaFilter = [GPUImageOpacityFilter new]; alphaFilter.opacity = 0.5; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];or:
GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageColorMatrixFilter *alphaFilter = [GPUImageColorMatrixFilter new]; alphaFilter.colorMatrix = (GPUMatrix4x4) { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.5 } }; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];Both GPUImage implementations return output as if alpha for input1 was 1.0.
I have looked at Lighten Blending Mode documentation in different sources on the internet and they all use this formula:
max(blend, base)Looking at the shader in implementation of GPUImageLightenBlendFilter it also uses the same formula:
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); gl_FragColor = max(textureColor, textureColor2);However, it seems that Photoshop and CoreImage have some extra manipulation with the alpha (probably similar to Gimp: https://github.com/GNOME/gimp/blob/783bbab8a889d4eba80b6a83f2e529937a73a471/app/operations/gimpoperationlightenonlymode.c).
Anyone has ideas how to include the alpha channel in the GPUImageLightenBlendFilter formula?
最满意答案
下面是具有不透明度和数量的GPUImageLightenBlendFilter着色器代码。
precision highp float; uniform sampler2D inputImageTexture; uniform sampler2D inputImageTexture2; uniform float alpha; // used for opacity.... uniform float amount; // amount of blend.... varying vec2 textureCoordinate; void main () { // Get samples from both layers vec4 dst = texture2D(inputImageTexture, textureCoordinate); vec4 src = texture2D(inputImageTexture2, textureCoordinate); src.a *= alpha; vec4 colour = vec4(0.0, 0.0, 0.0, 0.0); colour = vec4(max(dst, src).rgb, src.a) * src.a + dst * (1.0 - src.a); colour = clamp(colour, 0.0, 1.0); gl_FragColor.xyz = mix(dst, colour, amount).rgb; gl_FragColor.w = 1.0; }适合我......
I found this Shader code the best for my case:
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); textureColor.rgb *= textureColor.a; textureColor2.rgb *= textureColor2.a; lowp vec4 textureOut = max(textureColor, textureColor2); textureOut.rgb /= textureOut.a; gl_FragColor = textureOut;Found here: https://github.com/BradLarson/GPUImage/pull/1297
更多推荐
发布评论