در بسیاری از برنامهها به منظور درج امضای کاربر در مستندات، تصویر اسکن شدهی امضا اعمال میشود که در بیشتر مواقع بدلیل وجود پسزمینه و یا کدر بودن (Opaque)، نتیجه مطلوبی ارائه نمیدهد. برای مثال در یک از پروژه برای آنکه اثر امضا براحتی روی مستندات اعمال شود به گونهای که خطوط امضا اجازهی رسم شدن در نواحی مختلف را بدون پوشش محتوا بواسطه وجود پسزمینه داشته باشند منجر شد تا بااستفاده از Ces.SignatureExtractor از اثر امضا بجای تصویر اسکن شدهی امضا استفاده کنم.
استفاده از آن بسیار سادهست. ابتدا یک نمونه از کلاس Extractor را ایجاد میکنیم و سپس متد Extract را صدا میزنیم و نتیجه یک مقدار Bitmap خواهد بود. نمونه زیر با استفاده از UI پیاده سازی شده:
var extractor = new Ces.SignatureExtractor.Extractor();
this.pbFinalImage.Image = extractor.Extract(
_openFileDialog.FileName
, chkUseOriginalColor.Checked
, btnCustomColor.BackColor
, (byte)tbBackgroundPrecision.Value);
پارامترهای متد:
imagePath: آدرس تصویر اسکن شده که قرار است توسط متد پردازش شود.
useOriginalColor: با فعال بودن این گزینه نتیجه با همان رنگ اصلی برگشت داده میشود.
customColor: در صورت نیاز میتوان رنگ امضا را تغییر داد. قبل از آن باید گزینه useOriginalColor = false باشد.
precision: این مقدار بین 0 تا 255 میتواند تغییر کند و برای شناسایی و حذف رنگ پسزمینه می باشد. اگر پسزمینه خیلی کدر (Opaque) باشد باید این مقدار کاهش یابد.
نکته: رنگ امضا در تصویر اسکن شده نباید با خودکار قرمز باشد.
توضیحات کد:
ابتدا از آدرس ارسال شده یک تصویر با نام imgOriginal و سپس یک تصویر خالی با نام imgSignature و هم اندازه با imgSignature تعریف شده.
در ادامه دو حلقه تو در تو اجرا میشود که تمام پیکسلهای تصویر اصلی رو بررسی میکند و در تصویر imgSignature و در همان موقعیت اعمال میکند. اما این مساله دو نکته دارد 1) بدست آوردن روشنایی رنگ 2) آیا این پیکسل در محدودهی رنگ امضا میباشد یا خیر.
تعیین مرز بیرونی امضا (Boundry) که برنامه در انتها ناحیه خارج از مرز رو حذف و ناحیه امضا را بر میگرداند.
محاسبه ضریب Alpha
مقدار brightness از متد GetBrightness بدست آمده و در ادامه مقدار alpha که همان شفافیت رنگ است محاسبه شده است. اما منطق این ضرایب چیست؟ یک رنگ بطور عادی دارای شدت 1 است و در داتنت برای آنکه بتوان شفافیت رنگ را تنظیم کرد باید مقدار Alphaی رنگ رو مشخص کنیم که عدد 0 کاملا شفاف است و رنگ دیده نمیشود و عدد 255 که حداکثر شدت رنگ است. بنابراین اگر در خط امضا نقاطی وجود داشته باشد (مانند انتهای رسم امضا) که دارای شدت کمتری هستند باید رنگ جدید (در صورت مشخص کردن customColor) با همان شدت رسم شود. در غیر اینصورت تمام خطوط با شدت 1 رسم می شود و زیبایی امضا از بین خواهد رفت.
اما alpha چطور محاسبه شده؟ اگر اثر امضا در نقطهای حدود 20 درصد شفافیت کمتری داشته باشد در حقیقت 20 درصد از مقدار Alpha باید کم شود. بنابراین ضریب brightness که عددی float و بین 0 تا 1 است ابتدا از عدد 1 کم شده و سپس حاصل در 255 ضریب شده است تا میزان کاهش alpha بدست آید. حالا هر زمان که متد SetPixel رنگ را اعمکال میکند میتواند مقدار alpha را نیز در نظر بگیرد. با این روش اگر مسیر یک خط بدلیل کشیدن خودکار از آبی پررنگ به کمرنگ رسم شده باشد، برنامه ضمن تغییر رنگ، دقیقا همان شدت را در پیکسل جدید اعمال خواهد کرد.
خودکار قرمز ممنوع است
در ایجاد imgSignature برنامه باید بداند که آیا پیکسل جاری در محدوده خط امضا است یا خیر. تشخیص این موضوع برمبنای طیف رنگهایی است که دارای رنگ قرمز از محدود 0 تا 200 می باشند. اگر رنگی با این ویژگی تشخیص داده شود، برنامه از آن عبور خواهد کرد و هیچ پیکسلی را به تصویر نهایی انتقال نخواهد داد. به همین دلیل اگر رنگ امضا با خودکار قرمز باشد برنامه نمیتواند امضا را رسم کند.
نکته: اگر در زمان پردازش تصویر و بدلیل تیرگی پس زمینه، اثر امضا به همراه بخشی از پس زمینه به عنوان نتیجه برگشت داده شد، باید مقدار پارامتر precision را کمتر از 200 در نظر بگیرید (به مثال زیر توجه کنید).
مرز بیرونی امضا
پس از نهایی شده imgSignature و پیدا شدن مرز بیرونی امضا، برنامه محدوده داخل مرز امضا را در یک تصویر جدید رسم کرده و به عنوان نتیجه برگشت خواهد داد.
مثال: در مثال زیر ناحیه اضافه حذف و رنگ امضا به آبی تغییر کرده است.
ایجاد تصویر با precision = 226
002.png
ایجاد تصویر با precision = 185
003.png