كيفية إنشاء تصفية ختم فوتوشوب التناظرية في أي لغة تظليل بكسل؟
سؤال
كيفية إنشاء تصفية ختم فوتوشوب التناظرية في أي لغة تظليل بكسل؟ (أحتاج على الأقل تصفية خوارزمية ...)
المحلول
لقد نظرت إلى مرشح الطوابع في 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 ، جورج
لا تنتمي إلى StackOverflow