如何在任何像素着色语言中创建Photoshop印章滤镜模拟? [英] How to create Photoshop Stamp filter analog in any pixel shading language?

查看:219
本文介绍了如何在任何像素着色语言中创建Photoshop印章滤镜模拟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在任何像素着色语言中创建Photoshop Stamp滤镜模拟? (我至少需要过滤算法...)

解决方案

我已经看过Photoshop中的邮票过滤器,它看起来像一个阈值和一个强烈的模糊加在一起。

我使用了Horizo​​ntalGaussianBlur内核找到 Pixel Bender Basics文章Devnet
,只是增加了一个便宜的门槛。下面是我的内核的样子:

 < languageVersion:1.0;> 

内核邮票
<命名空间:toMaterial;
厂商:George Profenza;
版本:1;
description:尝试模拟Photoshop Stamp Filter。原始模糊代码:http://www.adobe.com/devnet/flash/articles/pixel_bender_basics_05.html;
>
{
输入image4 src;
输出pixel4 dst;

参数浮动阈值<
minValue:0.0;
defaultValue:0.5;
maxValue:1.0;
>;
参数int radius
<
minValue:1;
maxValue:6;
defaultValue:6;
>;

void
evaluatePixel()
{
pixel4 center,band1,band2,band3,band4,band5,band6;
float2 pos = outCoord();

//带中的示例图像
if(radius> 5){
pixel4 left = dst;
pixel4 right = dst;
left.x - = 6.0;
right.x + = 6.0;
band6 =左+右;
}
if(radius> 4){
pixel4 left = dst;
pixel4 right = dst;
left.x - = 5.0;
right.x + = 5.0;
band5 =左+右;
}
if(radius> 3){
pixel4 left = dst;
pixel4 right = dst;
left.x - = 4.0;
right.x + = 4.0;
band4 =左+右;
}
if(radius> 2){
pixel4 left = dst;
pixel4 right = dst;
left.x - = 3.0;
right.x + = 3.0;
band3 =左+右;
}
if(radius> 1){
pixel4 left = dst;
pixel4 right = dst;
left.x - = 2.0;
right.x + = 2.0;
band2 =左+右;
}
pixel4 left = dst;
pixel4 right = dst;
left.x - = 1.0;
right.x + = 1.0;
band1 =左+右;

dst = sampleNearest(src,pos);
// quick'n'dirty灰度
dst.rgb = float3(dst.r + dst.g + dst.b)* 0.333333333;
//阈值
if(dst.r if(dst.g <阈值)dst.g = 0.0; else dst.g = 1.0;
if(dst.b< threshold)dst.b = 0.0; else dst.b = 1.0;

center = dst;

//应用权值并计算结果像素
if(radius == 6)
{
dst =(band6 +(band5 * 12.0)+(band4 * 66.0)+(band3 * 220.0)+(band2 * 495.0)+(band1 * 792.0)+(center * 924.0))* 0.000244140625; // 4096.0;

if(radius == 5)
{
dst =(band5 +(band4 * 10.0)+(band3 * 45.0)+(band2 * 120.0)+(band1 * 210.0)+(center * 252.0))* 0.0009765625; // 1024.0;

if(radius == 4)
{
dst =(band4 +(band3 * 8.0)+(band2 * 28.0)+(band1 * 56.0)+(center * 70.0))* 0.00390625; // 256.0;

if(radius == 3)
{
dst =(band3 +(band2 * 6.0)+(band1 * 15.0)+(center * 20.0))* 0.015625 ; // 64.0;
}
if(radius == 2)
{
dst =(band2 +(band1 * 4.0)+(center * 6.0))* 0.0625; // 16.0 $ b如果(半径== 1)
{
dst =(band1 +(center * 2.0))* 0.25; // 4.0
}



$ / code $ / pre

这是远远不够完美的,很快在这个时候。这应该
给你一些想法虽然。
$ b

更新:



这是一个使用适当的灰度更新的版本,高斯模糊代码主要来自 Pixel Bender指南

 < languageVersion:1.0;> 

内核邮票
<命名空间:gp;
厂商:George Profenza;
版本:1;
description:试图做一个类似于Photoshop的邮票过滤器的过滤器,主要是从指南模糊代码:http://www.adobe.com/go/pixelbender_devguide;
>
{
input image4 source;
输出pixel4结果;

参数int blur<
minValue:1;
defaultValue:3;
maxValue:8;
>;
参数浮动阈值<
minValue:0.0;
maxValue:1.0;
defaultValue:0.5;
>;

void
evaluatePixel()
{
// blur
const float sigma = 2.0;
float c = 1.0 /(sqrt(2.0 * 3.1415926535)* sigma);
float ec = 2.0 * sigma * sigma;
float weight0 = exp( - (0.0 * 0.0)/ ec)* c;
float weight1 = exp( - (1.0 * 1.0)/ ec)* c;
if(blur> 1)float weight2 = exp( - (2.0 * 2.0)/ ec)* c;
if(blur> 2)float weight3 = exp( - (3.0 * 3.0)/ ec)* c;
if(blur> 3)float weight4 = exp( - (4.0 * 4.0)/ ec)* c;
if(blur> 4)float weight5 = exp( - (5.0 * 5.0)/ ec)* c;
if(blur> 5)float weight6 = exp( - (6.0 * 6.0)/ ec)* c;
if(blur> 6)float weight7 = exp( - (7.0 * 7.0)/ ec)* c;
if(blur> 7)float weight8 = exp( - (8.0 * 7.0)/ ec)* c;

float4 acc = float4(0.0);

acc + = sampleNearest(source,outCoord())* weight0;
acc + = sampleNearest(source,outCoord()+ float2(1.0,0.0))* weight1;
acc + = sampleNearest(source,outCoord()+ float2(-1.0,0.0))* weight1;
if(blur> 1){
acc + = sampleNearest(source,outCoord()+ float2(2.0,0.0))* weight2;
acc + = sampleNearest(source,outCoord()+ float2(-2.0,0.0))* weight2;
}
if(blur> 2){
acc + = sampleNearest(source,outCoord()+ float2(3.0,0.0))* weight3;
acc + = sampleNearest(source,outCoord()+ float2(-3.0,0.0))* weight3;
}
if(blur> 3){
acc + = sampleNearest(source,outCoord()+ float2(4.0,0.0))* weight4;
acc + = sampleNearest(source,outCoord()+ float2(-4.0,0.0))* weight4;
}
if(blur> 4){
acc + = sampleNearest(source,outCoord()+ float2(5.0,0.0))* weight5;
acc + = sampleNearest(source,outCoord()+ float2(-5.0,0.0))* weight5;
}
if(blur> 5){
acc + = sampleNearest(source,outCoord()+ float2(6.0,0.0))* weight6;
acc + = sampleNearest(source,outCoord()+ float2(-6.0,0.0))* weight6;
}
if(blur> 6){
acc + = sampleNearest(source,outCoord()+ float2(7.0,0.0))* weight7;
acc + = sampleNearest(source,outCoord()+ float2(-7.0,0.0))* weight7;
}
if(blur> 7){
acc + = sampleNearest(source,outCoord()+ float2(8.0,0.0))* weight8;
acc + = sampleNearest(source,outCoord()+ float2(-8.0,0.0))* weight8;
}
//灰度
浮点亮度= 0.299 * acc.r + 0.587 * acc.g + 0.114 * acc.b;
acc = float4(luma,luma,luma,1.0);
//阈值
if(acc.r if(acc.g <阈值)acc.g = 0.0;其他acc.g = 1.0;
if(acc.b< threshold)acc.b = 0.0;别的acc.b = 1.0;

result = acc;


code

$ b

注意:我应用了阈值之后的模糊,所以结果不是一个邮票过滤器,而是接近。



HTH,
George


How to create Photoshop Stamp filter analog in any pixel shading language? (I need at least filter algorithm...)

解决方案

I've look at the Stamp Filter in Photoshop and it looks like a Threshold and a strong Blur added together.

I've used the HorizontalGaussianBlur kernel found Pixel Bender Basics Article on Devnet and just added a cheap threshold. Here is how my kernel looks like:

<languageVersion : 1.0;>

kernel stamp
<   namespace : "toMaterial";
    vendor : "George Profenza";
    version : 1;
    description : "Attempt to simulate Photoshop Stamp Filter. Original blur code: http://www.adobe.com/devnet/flash/articles/pixel_bender_basics_05.html";
>
{
    input image4 src;
    output pixel4 dst;

    parameter float threshold<
        minValue: 0.0;
        defaultValue:0.5;
        maxValue:1.0;
    >;
    parameter int radius
    <
        minValue : 1;
        maxValue : 6;
        defaultValue : 6;
    >;

    void
    evaluatePixel()
    {
        pixel4 center, band1, band2, band3, band4, band5, band6;
        float2 pos = outCoord();

        //Sample image in bands
        if(radius > 5) {
            pixel4 left  = dst;
            pixel4 right = dst;
            left.x -= 6.0;
            right.x += 6.0;
            band6 = left+right;
        }
        if(radius > 4) {
            pixel4 left  = dst;
            pixel4 right = dst;
            left.x -= 5.0;
            right.x += 5.0;
            band5 = left+right;
        }
        if(radius > 3) {
            pixel4 left  = dst;
            pixel4 right = dst;
            left.x -= 4.0;
            right.x += 4.0;
            band4 = left+right;
        }
        if(radius > 2) {
            pixel4 left  = dst;
            pixel4 right = dst;
            left.x -= 3.0;
            right.x += 3.0;
            band3 = left+right;
        }
        if(radius > 1) {
            pixel4 left  = dst;
            pixel4 right = dst;
            left.x -= 2.0;
            right.x += 2.0;
            band2 = left+right;
        }
        pixel4 left  = dst;
        pixel4 right = dst;
        left.x -= 1.0;
        right.x += 1.0;
        band1 = left+right;

        dst = sampleNearest(src,pos);
        //quick'n'dirty grayscale
        dst.rgb = float3(dst.r + dst.g + dst.b) * 0.333333333;
        //threshold
        if(dst.r < threshold) dst.r = 0.0; else dst.r = 1.0;
        if(dst.g < threshold) dst.g = 0.0; else dst.g = 1.0;
        if(dst.b < threshold) dst.b = 0.0; else dst.b = 1.0;

        center = dst;

        //Apply weights and compute resulting pixel
       if( radius == 6 )
       {
            dst = (band6 + (band5 * 12.0) + (band4 * 66.0) + (band3 * 220.0) + (band2 * 495.0) + (band1 * 792.0) + (center * 924.0)) * 0.000244140625;//4096.0;
       }
       if( radius == 5 )
       {
            dst = (band5 + (band4 * 10.0) + (band3 * 45.0) + (band2 * 120.0) + (band1 * 210.0) + (center * 252.0)) * 0.0009765625;//1024.0;
       }       
       if( radius == 4 )
       {
            dst = (band4 + (band3 * 8.0) + (band2 * 28.0) + (band1 * 56.0) + (center * 70.0)) * 0.00390625;//256.0;
       }
       if( radius == 3 )
       {
            dst = (band3 + (band2 * 6.0) + (band1 * 15.0) + (center * 20.0)) * 0.015625;//64.0;
       }
       if( radius == 2 )
       {
            dst = (band2 + (band1 * 4.0) + (center * 6.0)) * 0.0625;//16.0
       }
       if( radius == 1 )
       {
            dst = (band1 + (center * 2.0)) * 0.25;//4.0
       }

    }
}

This is far from perfect, it is what I could hack quickly at this hour. This should give you some ideas though.

UPDATE:

Here is an updated version using proper grayscale and the Gaussian Blur code is mostly from the Pixel Bender Guide.

<languageVersion : 1.0;>

kernel Stamp
<   namespace : "gp";
    vendor : "George Profenza";
    version : 1;
    description : "Attempt to do a filter similar to Photoshop's Stamp Filter, blur code mostly from the guide: http://www.adobe.com/go/pixelbender_devguide";
>
{
    input image4 source;
    output pixel4 result;

    parameter int blur<
        minValue:1;
        defaultValue:3;
        maxValue:8;
    >;
    parameter float threshold<
        minValue:0.0;
        maxValue:1.0;
        defaultValue:0.5;
    >;

    void
    evaluatePixel()
    {
        //blur
        const float sigma = 2.0;
        float c = 1.0 / ( sqrt(2.0 * 3.1415926535 ) * sigma );
        float ec = 2.0 * sigma * sigma;
        float weight0 = exp( -( 0.0 * 0.0 ) / ec ) * c;
        float weight1 = exp( -( 1.0 * 1.0 ) / ec ) * c;
        if(blur > 1) float weight2 = exp( -( 2.0 * 2.0 ) / ec ) * c;
        if(blur > 2) float weight3 = exp( -( 3.0 * 3.0 ) / ec ) * c;
        if(blur > 3) float weight4 = exp( -( 4.0 * 4.0 ) / ec ) * c;
        if(blur > 4) float weight5 = exp( -( 5.0 * 5.0 ) / ec ) * c;
        if(blur > 5) float weight6 = exp( -( 6.0 * 6.0 ) / ec ) * c;
        if(blur > 6) float weight7 = exp( -( 7.0 * 7.0 ) / ec ) * c;
        if(blur > 7) float weight8 = exp( -( 8.0 * 7.0 ) / ec ) * c;

        float4 acc = float4( 0.0 );

        acc += sampleNearest( source, outCoord() ) * weight0;
        acc += sampleNearest( source, outCoord() + float2( 1.0, 0.0 ) ) * weight1;
        acc += sampleNearest( source, outCoord() + float2( -1.0, 0.0 ) ) * weight1;
        if(blur > 1) {
            acc += sampleNearest( source, outCoord() + float2( 2.0, 0.0 ) ) * weight2;
            acc += sampleNearest( source, outCoord() + float2( -2.0, 0.0 ) ) * weight2;
        }
        if(blur > 2) {
            acc += sampleNearest( source, outCoord() + float2( 3.0, 0.0 ) ) * weight3;
            acc += sampleNearest( source, outCoord() + float2( -3.0, 0.0 ) ) * weight3;
        }
        if(blur > 3) {
            acc += sampleNearest( source, outCoord() + float2( 4.0, 0.0 ) ) * weight4;
            acc += sampleNearest( source, outCoord() + float2( -4.0, 0.0 ) ) * weight4;
        }
        if(blur > 4) {
            acc += sampleNearest( source, outCoord() + float2( 5.0, 0.0 ) ) * weight5;
            acc += sampleNearest( source, outCoord() + float2( -5.0, 0.0 ) ) * weight5;
        }
        if(blur > 5) {
            acc += sampleNearest( source, outCoord() + float2( 6.0, 0.0 ) ) * weight6;
            acc += sampleNearest( source, outCoord() + float2( -6.0, 0.0 ) ) * weight6;
        }
        if(blur > 6) {
            acc += sampleNearest( source, outCoord() + float2( 7.0, 0.0 ) ) * weight7;
            acc += sampleNearest( source, outCoord() + float2( -7.0, 0.0 ) ) * weight7;
        }
        if(blur > 7) {
            acc += sampleNearest( source, outCoord() + float2( 8.0, 0.0 ) ) * weight8;
            acc += sampleNearest( source, outCoord() + float2( -8.0, 0.0 ) ) * weight8;
        }
        //grayscale
        float luma = 0.299 * acc.r + 0.587 * acc.g + 0.114 * acc.b;
        acc = float4(luma,luma,luma,1.0);
        //threshold
        if(acc.r < threshold) acc.r = 0.0; else acc.r = 1.0;
        if(acc.g < threshold) acc.g = 0.0; else acc.g = 1.0;
        if(acc.b < threshold) acc.b = 0.0; else acc.b = 1.0;

        result = acc;
    }
}

Note: I applied the threshold after the blur, so the result is not exactly a Stamp Filter but close.

HTH, George

这篇关于如何在任何像素着色语言中创建Photoshop印章滤镜模拟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆