كيفية إنشاء تصفية ختم فوتوشوب التناظرية في أي لغة تظليل بكسل؟

StackOverflow https://stackoverflow.com/questions/2345436

  •  23-09-2019
  •  | 
  •  

سؤال

كيفية إنشاء تصفية ختم فوتوشوب التناظرية في أي لغة تظليل بكسل؟ (أحتاج على الأقل تصفية خوارزمية ...)

هل كانت مفيدة؟

المحلول

لقد نظرت إلى مرشح الطوابع في Photoshop ويبدو وكأنه عتبة وطمس قوي تمت إضافته معًا.

لقد استخدمت kernel horizontalgaussianblur مقالة Pixel Bender Basics على DevNetوأضاف فقط عتبة رخيصة. إليكم كيف تبدو نواة بلدي:

<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
       }

    }
}

هذا بعيد عن الكمال ، إنه ما يمكنني اختراقه بسرعة في هذه الساعة. هذا يجب أن يعطيك بعض الأفكار رغم ذلك.

تحديث:

فيما يلي نسخة محدثة باستخدام رمادي مناسب ، ويكون رمز الضبط الغاوسي في الغالب من دليل البكسل بندر.

<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;
    }
}

ملحوظة: لقد قمت بتطبيق العتبة بعد الضبابية ، وبالتالي فإن النتيجة ليست مرشح الطوابع تمامًا ولكنها تغلق.

HTH ، جورج

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top