C# - Image Processing (Gamma Algorithm)

Posted by ေတဇာလင္း Friday, 24 February 2017 1 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# နဲ႔ Image တစ္ခုကို Gamma Algorithm ကိုအသံုးျပဳၿပီးေတာ့ Color ေတြကို Control လုပ္ႏိုင္တာေလးကို ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
Gamma ဆိုတာ non-linear operation တစ္ခုပါ။ Gamma correction, gamma non-linearity, gamma encoding, ... စသည္ျဖင့္ အမ်ိဳးမ်ိဳးေခၚေ၀ၚၾကပါတရ္။ မည္သို႔ပင္ဆိုေစ Gamma ရဲ႕ အလုပ္ကေတာ့ Image တစ္ခုရဲ႕ light and dark တန္ဖိုးေတြကို encode and decond လုပ္ဖို႔ပါ။ တစ္နည္းအားျဖင့္ Brightness ကို Control လုပ္တာပါ။ အလင္း/အေမွာင္ကို control လုပ္တရ္ဆုိလို႔ ေရွ႕မွာေလ့လာခဲ့ၿပီးျဖစ္တဲ့ Brightness နဲ႔ သြားမေရာေစခ်င္ပါ။ Gamma Operation က Brightness Operation နဲ႔ ပိုၿပီးရႈပ္ေထြးပါတရ္။ Gamma Algorithm ကိုေတာ့ အလင္း/အေမွာင္ ပံုစံ မမွန္ေသာ Image မ်ားကို မိမိစိတ္ႀကိဳက္ R, G, B Color Value ကို Brithtness ကစားၿပီး encode လုပ္တဲ့အခ်ိန္မွာ သံုးပါတရ္။ Brightness တုန္းက R, G, B Color value ကို -255 to 255 နဲ႔ radio တစ္ခုတည္းမွာ ကစားႏိုင္ေပမဲ့ Gamma မွာေတာ့ 0.2 to 5 ၾကားမွာ R, G, B Color Value ကို channel တစ္ခုစီအလိုက္ ကစားႏိုင္ပါလိမ့္မရ္။ ေအာက္မွာ Algorithm နဲ႔ Example ေလးကို ၾကည့္လိုက္ရင္ နားလည္သြာပါလိမ့္မရ္။ အနည္းငယ္ ရွင္းျပရမရ္ဆိုရင္ေတာ့... ပထမဦးဆံုး Pixel ကို Detect လုပ္ၿပီး RGB Color Value ေတြကို ဆြဲထုတ္ပါတရ္။ ဒုတိယအဆင့္မွာေတာ့ ရလာတဲ့ RGB Color Value ေတြကို Gamma Formula ထဲကိုျဖတ္ၿပီး RGB Color Value အသစ္ေတြကို ဖန္တီးယူပါတရ္။ Gamma Formula ပံုစံကေတာ့...
RGB = (255.0 * Math.Pow(Original_Color / 255.0, 1.0 / Gamma));
အခုလိုျဖစ္ပါတရ္။ တတိယအဆင့္မွာေတာ့ ရရွိလာတဲ့ Color Value အသစ္ေတြကို မူလ Pixel ရဲ႕ RGB Color Value ေနရာေတြမွာ ျပန္အစားထိုးလိုက္တာပါ။ ဒီနည္းအတိုင္း last Pixel ေရာက္သည္အထိ တြက္ထုတ္ၿပီး Gamma Image တစ္ခုအျဖစ္ ဖန္တီးယူလိုက္တာပဲ ျဖစ္ပါတရ္ဗ်။ ဥပမာအေနနဲ႔ေတာ့ က်ေနာ္ Red Color တစ္ခုကို Gramma တြက္ျပထားပါတရ္။ နားလည္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။ အထက္မွာရွင္းျပခဲ့တာကေတာ့ Gamma Algorithm ရဲ႕ Color Encode Formual ပံုစံပါ။ မိတ္ေဆြတို႔အေနနဲ႔ Gamma ခ်ိန္ယူၿပီးသား Image တစ္ခုကို မူလပံုစံ သို႔မဟုတ္ ႀကိဳက္ႏွစ္သက္ရာ Color နဲ႔ Decode ျပန္လုပ္ခ်င္တရ္ဆိုရင္ျဖင့္ ေအာက္က Formula ကို ျပန္သံုးႏိုင္ပါတရ္ဗ်။
Original = 255.0 * Math.Pow(encode/255.0, gamma);
အေပၚမွာ က်ေနာ္ Red Color 120 ကုိ Gamma ကုိသံုးၿပီး Encode လုပ္ခဲ့တာ 139 ရခဲ့ပါတရ္။ မိတ္ေဆြတို႔အေနနဲ႔ ဒီ Decode Formual ကိုသံုးၿပီး Decode ျပန္လုပ္ၾကည့္ပါ။ Red Color 120 ျပန္ရပါလိမ့္မရ္ဗ်။
မွတ္ခ်က္။ Gamma Input range က 0.2 to 5 အထိပဲရွိတာကို သတိျပဳပါ။ Gamma Value = 1 က Gamma Processing မလုပ္ရေသးတဲ့ မူလ Color Value ျဖစ္ၿပီး 1 နဲ႔ 0.2 ၾကားကေတာ့ အေမွာင္ဘက္ကို Control လုပ္မရ္႕ Gamma Value ျဖစ္ပါတရ္။ 1 to 5 ကေတာ့ အလင္းဘက္သို႔ Control လုပ္မရ္႕ Gamma Value ပဲျဖစ္ပါတရ္ဗ်ာ။
ကဲ... ဒီေလာက္ဆိုရင္ေတာ့ Gamma Algorithm ရဲ႕ သေဘာတရားကို သိၿပီလို႔ ထင္ပါတရ္။ က်ေနာ္တို႔ GUI ေဖာက္ Coding ေရးၿပီး လက္ေတြ႔ေလ့လာၾကည့္ရေအာင္။ ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(2)ခုနဲ႔ PictureBox(2)ခု၊ TrackBar(3)ခုနဲ႔ Label(3)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုေဖာ္ ဖန္တီးႏိုင္ပါတရ္ဗ်။
ဒီမွာ TrackBar ရဲ႕ Range ကို 4 to 100 ေပးထားတာကေတာ့ က်ေနာ္တို႔ Gamma ရဲ႕ Inupt Range ျဖစ္တဲ့ 0.2 to 5 ၾကား ကစားႏိုင္ေအာင္ပါ။ 4 to 100 ေပးၿပီး 0.2 to 5 ျဖစ္ေအာင္ က်ေနာ္ကေတာ့ ေအာက္ကပံုစံအတိုင္း တြက္ထုတ္ထားပါတရ္။
Gamma = 0.05 * TrackBarValue;
အခုလိုပါ။ TrackBar ရဲ႕ lower bound ျဖစ္တဲ့ 4 ကို 0.05 နဲ႔ေျမွာက္ၾကည့္ပါ။ က်ေနာ္တို႔ Gamma Value ရဲ႕ lower bound ျဖစ္တဲ့ 0.2 ကိုရပါလိမ့္မရ္။ ဒီလိုပါပဲ TrackBar ရဲ႕ upper bound ျဖစ္တဲ့ 100 ကို 0.05 နဲ႔ေျမွာက္ၾကည့္ပါ။ က်ေနာ္တို႔ Gamma Value ရဲ႕ upper bound ျဖစ္တဲ့ 5 ကိုရပါလိမ့္မရ္ဗ်ာ။ ဒါဆိုရင္ေတာ့ TrackBar ကိုႀကိဳက္သလိုကစားရင္ေတာင္ က်ေနာ္တို႔ လိုခ်င္ေနတဲ့ Gamma Input Range ျဖစ္တဲ့ 0.2 to 5 ၾကားပဲ ရွိေနပါလိမ့္မရ္ဗ်။ logic ကေတာ့ သခၤ်ာကို အေျခခံထားပါတရ္။ Math အားေကာင္းရင္ျဖင့္ Programming Logic ေကာင္းပါလိမ့္မရ္ဗ်ာ။ ေလ့လာၾကပါလို႔ တိုက္တြန္းပါရေစ။
ဒီေလာက္ဆိုရင္ေတာ့ က်ေနာ္တို႔ Gamma Processing မွာ အသံုးျပဳမရ္႕ Algorithm ေတြ logic ေတြ အၾကမ္းဖ်ဥ္းနားလည္သြားပါၿပီ။ က်ေနာ္တို႔ Coding ေရးၾကည့္ၾကမရ္။ ဒါကေတာ့ ပထမဆံုး Processing လုပ္မရ္႕ Image ကို PictureBox ေပၚသို႔ ဆြဲတင္တဲ့အခ်ိန္မွာပဲ Gamma Processing အတြက္ လိုအပ္တာမ်ားကို Initial လုပ္လိုက္တာပါ။ Global အေနနဲ႔ redGamma, greenGamma, blueGamma တို႔ကို 1 assign လုပ္ထားတာကေတာ့ က်ေနာ္အေပၚမွတ္ခ်က္မွာ ေျပာခဲ့တဲ့အတိုင္း Image ကို Gamma Processing မလုပ္ရေသးတဲ့ 1 အေျခအေနမွာ initial လုပ္ခ်င္လို႔ပါ။ ကနဦးမွာ user information အျဖစ္ label ေတြနဲ႔ Gamma value ေတြကို 1 ေပးထားပါတရ္။ ေနာက္ TrackBar Value ေတြကို 20 ေပးထားတာကလည္း Gamma Processing မလုပ္ရေသးတဲ့ 1 အေျခအေနမွာ initial လုပ္ခ်င္လို႔ပါပဲ(Gamma = 20 * 0.05 = 1)။ နားလည္ႏိုင္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။ ဒါကေတာ့ Gamma Processing အတြက္ Method ခြဲေရးထားတာပါ။ Method ကိုေတာ့ Processing လုပ္မရ္႕ Image နဲ႔အတူ RGB Gamma Value ေတြကို Parameter Passing လုပ္ထားပါတရ္။ Pixel Detection လုပ္တဲ့ လုပ္ငန္းစဥ္ကိုေတာ့ က်ေနာ္တို႔ ေရွ႕မွာေလ့လာခဲ့ၿပီးျဖစ္တဲ့ Fast Image Processing ေလ့က်င့္ခန္းအတိုင္း Detect လုပ္ထားပါတရ္။ နားမလည္ေသးတဲ့ မိတ္ေဆြတို႔အတြက္ ေရွ႕သင္ခန္းစာေတြကို ျပန္ဖတ္ေပးပါလို႔ တိုက္တြန္းပါရေစ။ R, G, B Color Value ေတြကို Gamma ေျပာင္းယူပံုအဆင့္ဆင့္ကိုေတာ့ က်ေနာ္ အေပၚမွာ ဥပမာနဲ႔ အေသစိတ္ရွင္းျပခဲ့ပါတရ္။ Coding မွာ ခက္ခဲတာ ဘာမွမပါလို႔ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
ဒါကေေတာ့ TrackBar သို႔မဟုတ္ RBG Gamma Value ေတြရဲ႕ ေျပာင္းလဲအမႈအေပၚ မူတည္ၿပီး Gamma Image ေျပာင္းလဲယူဖို႔အတြက္ Calling Method အေျခအေနပါ။ RBG Gamma Value ေတြအတြက္ Track Bar သံုးခုကို သံုးထားတဲ့အတြက္ TrackBar သံုးခုစလံုးမွ Method ကို Calling လုပ္ထားပါတရ္။ Coding ကေတာ့ အရမ္းကို ရိုးရွင္းပါတရ္။ Gamma Method က သတ္မွတ္ထားတဲ့ Parameter အတိုင္း Value ေတြကို မွန္မွန္ကန္ကန္ Assign လုပ္ေပးလိုက္ယံုပါပဲဗ်ာ။ if( )statement နဲ႔စစ္ထားတာကေတာ့ Processing လုပ္မရ္႕ Image ကုိဆြဲတင္ၿပီး ရွိ/မရွိ သိခ်င္လို႔ပါ။ Default Image အတြက္ေတာ့ ရိုးရိုးရွင္းရွင္းပါပဲ။ အားလံုးကို Gamma Processing မလုပ္ရေသးတဲ့ အေျခအေနကို ျပန္ပို႔ထားလိုက္တာပါ။ မိတ္ေဆြတို႔ အားလံုးကို ၿခံဳငံုနားလည္သြားေအာင္ ေအာက္မွာ Coding အျပည့္အစံုကို ေလ့လာႏိုင္ပါတရ္ဗ်။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Image Processing (Negative Algorithm)

Posted by ေတဇာလင္း Wednesday, 22 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Image တစ္ခုကို Negative View ပုံစံနဲ႔ ထုတ္ၾကည့္ႏိုင္တာေလးကို ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
ဖလင္ကင္မရာေတြေခာတ္ကို မွီခဲ့တဲ့ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမတို႔အတြက္ေတာ့ Negative Image ဆိုတာကို သိၾကမရ္ထင္ပါတရ္။ Negative Film လိပ္ေလးေတြကို တယုတယသိမ္းၿပီး ဓါတ္ပံုအျဖစ္ ျပန္ျပန္ကူးယူခဲ့ၾကရတာကိုဗ်။ Negative ဆိုတာက ရုိးရိုးရွင္းရွင္း ေျပာရရင္ Invert လုပ္လိုက္တာပါ။ 1 ဆိုရင္ 0 ေျပာင္း၊ အျဖဴဆိုအမဲ ေျပာင္းလိုက္တာေပါ့။ Pixel တစ္ခုစီမွာရွိတဲ့ Color ေတြကို Invert လုပ္ပစ္ႏိုင္မွာသာ က်ေနာ္တို႔လိုခ်င္တဲ့ Negative Image တစ္ခုကိုရရွိမွာ မဟုတ္လားဗ်။ Color Range 0 to 255 ၾကားမွ ဘာျဖစ္လာမရ္မွန္းမသိတဲ့ Color Value ကို Invert လုပ္ဖို႔ တစ္ခုတည္းေသာ နည္းလမ္းရွိပါတရ္။ ဒါကေတာ့ Color ရဲ႕ Upper Bound ျဖစ္တဲ့ 255 ထဲက Detect လုပ္လုိ႔ရရွိတဲ့ Color Value ကိုႏုတ္လိုက္ယံုပါပဲ။ ေအာက္မွာ အဆင့္လိုက္ အေသးစိတ္ Algorithm ေလးကို ၾကည့္လိုက္ပါ။ အနည္းငယ္ ရွင္းျပရမရ္ဆိုရင္ေတာ့... ပထမအဆင့္မွာ Image ရဲ႕ Pixel တစ္ခုကို Detect လုပ္ၿပီး R, G, B Color Value ေတြကို ဆြဲထုတ္ယူပါတရ္။ ဒုတိယအဆင့္မွာေတာ့ Color range ရဲ႕ Upper Bound ျဖစ္တဲ့ 255 ထဲက Detect ရရွိေသာ R, G, B Color တန္ဖိုးေတြကို နဳတ္ပါတရ္။ တတိယအဆင့္မွာေတာ့ အသစ္ရရွိလာေသာ R, G, B တန္ဖိုးေတြကို မူလ Pixel ရဲ႕ R, G, B Color တန္ဖိုးေတြေနရာကို ျပန္အစားထိုးလိုက္တာပါ။ ဒီနည္းလမ္းအတိုင္းပဲ Last Pixel ေရာက္သည္အထိ အလုပ္လုပ္ေစၿပီး Color Image တစ္ခုကို Negative Image အျဖစ္သို႔ ေျပာင္းလဲယူလိုက္တာပဲ ျဖစ္ပါတရ္ဗ်။ ဥပမာေလးနဲ႔တြဲၿပီးရွင္းထားလို႔ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္။
မွတ္ခ်က္။ ဒီ Algorithm က Color Image ကုိ Negative Image အျဖစ္ ေျပာင္းလဲႏိုင္သလို၊ Negative Image ကို Color Image အျဖစ္ ျပန္လည္ေျပာင္းလဲယူႏိုင္ပါတရ္ဗ်။
ကဲ... ဒီေလာက္ဆိုရင္ေတာ့ Negative Algorithm ရဲ႕ သေဘာတရားကို သိၿပီလို႔ ထင္ပါတရ္။ က်ေနာ္တို႔ GUI ေဖာက္ Coding ေရးၿပီး လက္ေတြ႔ေလ့လာၾကည့္ရေအာင္။ ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(2)ခုနဲ႔ PictureBox(2)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုေဖာ္ ဖန္တီးႏိုင္ပါတရ္ဗ်။
NegativeImage( ) Method ေလးကို ေလ့လာၾကည့္ပါ့မရ္။ Button Click_Event ကိုသာ သံုးထားတဲ့အတြက္ေၾကာင့္ Negative Image Button ကို D_Click ေပးၿပီး ေအာက္ပါ Coding ေလးကို ေရးယူလိုက္ပါဗ်ာ။ Method ကိုေတာ့ Processing လုပ္မရ္႕ Image ကုိ Parameter Passing လုပ္ထားပါတရ္။ Pixel Detection လုပ္တဲ့ လုပ္ငန္းစဥ္ကိုေတာ့ က်ေနာ္တို႔ ေရွ႕မွာေလ့လာခဲ့ၿပီးျဖစ္တဲ့ Fast Image Processing ေလ့က်င့္ခန္းအတိုင္း Detect လုပ္ထားပါတရ္။ နားမလည္ေသးတဲ့ မိတ္ေဆြတို႔အတြက္ ေရွ႕သင္ခန္းစာေတြကို ျပန္ဖတ္ေပးပါလို႔ တိုက္တြန္းပါရေစ။ R, G, B Color Value ေတြကို Invert ေျပာင္း Negative လုပ္ယူပံုအဆင့္ဆင့္ကိုေတာ့ က်ေနာ္ အေပၚမွာ ဥပမာနဲ႔ အေသစိတ္ရွင္းျပခဲ့ပါတရ္။ Coding မွာ ခက္ခဲတာ ဘာမွမပါလို႔ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။ ဒါကေတာ့ Calling Method ပံုစံပါ။ if( )statement နဲ႔စစ္ထားတာကေတာ့ Processing လုပ္မရ္႕ Image ကုိဆြဲတင္ၿပီး ရွိ/မရွိ သိခ်င္လို႔ပါ။ မိတ္ေဆြတို႔ အားလံုးကို ၿခံဳငံုနားလည္သြားေအာင္ ေအာက္မွာ Coding အျပည့္အစံုကို ေလ့လာႏိုင္ပါတရ္ဗ်။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Image Processing (Brightness Algorithm)

Posted by ေတဇာလင္း Monday, 20 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Image တစ္ခုကို Brithtness အတိုး/အေလွ်ာ့လုပ္ၿပီး အလင္း/အေမွာင္ ခ်ိန္ယူႏိုင္တာေလးနဲ႔ပါတ္သတ္ၿပီး ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
Brightness ဆိုတာကေတာ့ Image တစ္ခုကို အလင္း/အေမွာင္ ခ်ိန္ညိႈႏိုင္ဖို႔အတြက္ အသံုးျပဳတဲ့ Algorithm တစ္ခုပဲ ျဖစ္ပါတရ္။ Image တစ္ခုကို Region ေတြ အေသးစိတ္ခြဲၿပီး Pixel တစ္ခုခ်င္းစီကို Detect လုပ္ကာ စိတ္ႀကိဳက္ အလင္း/အေမွာင္ကို ခ်ိန္ယူႏိုင္ပါတရ္။ အႏုစိတ္ႏိုင္ေလ ပံုထြက္ေကာင္းေလပါပဲဗ်။ ဒီေလ့က်င့္ခန္းမွာေတာ့ Image ရဲ႕ Pixel အားလံုးကို Detect လုပ္ၿပီး Brightness အတိုး/အေလွ်ာ့ကို စိတ္ႀကိဳက္ကစားၾကည့္မွာ ျဖစ္ပါတရ္။ အလင္း/အေမွာင္ပဲ ခ်ိန္တာေလးကို ပံုထြက္ေကာင္းတရ္ေျပာလို႔ အမ်ိဳးေတာ့ မထင္ၾကပါနဲ႔ Camera အသံုးျပဳဖူးသူေတြနဲ႔ ဆယ္ဖီသမားေတြအတြက္ကေတာ့ မီး အလင္း/အေမွာင္ရဲ႕ အေရးပါမႈကို ေကာင္းေကာင္း သိၾကမရ္ထင္ပါတရ္။ ရုပ္ရွင္ေတြမွာ မီးထိုး၊ မွန္ထိုးတာေတြကလည္း ဒီ အလင္း/အေမွာင္ကို စိတ္ႀကိဳက္ ကစားၾကတာပါ။
Brightness က အလင္း/အေမွာင္ ခ်ိန္ယူတာလို႔ ေျပာခဲ့ပါတရ္။ ဒီေတာ့ Brightness ကို ေလ့လာတဲ့အခါ အလင္းနဲ႔အေမွာင္ဆိုၿပီ ႏွစ္ပိုင္းခြဲၿပီး ေလ့လာႏိုင္ပါတရ္။ အလင္းဘက္ကိုပဲသြားသြား၊ အေမွာင္ဘက္ကိုပဲသြားသြား Color range က (0 to 255) သာရွိလို႔ ဒီ scope ထဲက လြတ္သြားလို႔မရပါဘူး။ ဒီေတာ့ က်ေနာ္တုိ႔ အလင္း/အေမွာင္ကို ကစားလို႔ရတဲ့ Range က (-255 to +255) ေပါ့။
Algorithm ကိုခ်ဥ္းကပ္တဲ့ ပံုစံကေတာ့ ထူးထူးျခားျခားမရွိပါဘူးဗ်။ ပထမဦးဆံုး Pixel တစ္ခုကို Detect လုပ္ၿပီး R, G, B Color Value ေတြကို ဆြဲထုတ္ပါတရ္။ ရလာတဲ့ R, G, B တန္ဖိုးေတြကိုမွ မိမိတို႔လိုခ်င္တဲ့ အလင္း/အေမွာင္ တန္ဖိုးနဲ႔ ေပါင္းေပးၿပီး မူရင္း Pixel ရဲ႕ R, G, B value ေတြထဲ ျပန္ထည့္ေပးလိုက္တာပါ။ အလင္းဘက္သြားခ်င္ရင္ အေပါင္းတန္ဖိုးနဲ႔ ေပါင္းမရ္။ အေမွာင္ဘက္သြားခ်င္ရင္ အႏုတ္တန္ဖိုးနဲ႔ ေပါင္းေပးယံုေပါ့။ ဥပမာ အလင္းဘက္ကို သြားမရ္ဆိုပါစို႔-
Brightness Value = 45;
Pixel = RGB(120, 114, 50);
Brightness Processing,
Pixel = RGB(120+45, 114+45, 50+45); = RGB(165, 159, 95);

ဒီလိုပါပဲ။ အေမွာင္ဘက္ကို သြားမရ္ဆိုရင္ေတာ့...
Brightness Value = -45;
Pixel = RGB(120, 114, 50);
Brightness Processing,
Pixel = RGB(120+(-45), 114+(-45), 50+(-45)); = RGB(75, 69, 5);
ကဲ... ဒီေလာက္ဆိုရင္ေတာ့ Brightness Algorithm ရဲ႕ သေဘာတရားကို သိၿပီလို႔ ထင္ပါတရ္။ က်ေနာ္တို႔ GUI ေဖာက္ Coding ေရးၿပီး လက္ေတြ႔ေလ့လာၾကည့္ရေအာင္။ ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(1)ခု၊ Label(1)ခု၊ PictureBox(2)ခုနဲ႔ TrackBar(1)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုေဖာ္ ဖန္တီးႏိုင္ပါတရ္ဗ်။
ဒီေန႔ ေလ့က်င့္ခန္းမွာေတာ့ Brightness Processing အတြက္ TrackBar ကိုသံုးထားပါတရ္။ TrackBar ကို Initial Value = 255 ေပးထားတာကေတာ့ Brightness In/Out အတြက္ TrackBar ကို စမွတ္ 255 မွာ Zero Line ခ်လိုက္တာပါ။ ဒါမွ ကနဦး ဆြဲတင္လိုက္ေသာ Image ဟာ 255(0%)မွာ ေဖာ္ျပၿပီး 255 ေအာက္ငယ္သြားရင္ Bright Out Process ျဖစ္တဲ့ အေမွာင္ဘကိုကုိလုပ္္ကာ 255 ထက္မ်ားသြားရင္ေတာ့ Bright In Process ျဖစ္တဲ့ အလင္းဘက္ကိုလုပ္ပါလို႔ ခိုင္းလို႔ရမွာပါ။ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္။ ဒီေတာ့ TrackBar ရဲ႕ Value အခ်ိန္းအေျပာင္းေပၚမူတည္ၿပီး Brightness Result ေျပာင္းလဲ လုပ္ေဆာင္သြားမွာျဖစ္ပါတရ္။ TrackBar ကို D-Click ေပးၿပီး ေအာက္က Method ေလးကို ေရးယူလိုက္ပါဗ်ာ။ Method ကိုေတာ့ Processing လုပ္မရ္႕ Image နဲ႔ Brightness Changing အတြက္ Value ကုိ Parameter Passing လုပ္ထားပါတရ္။ Pixel Detection လုပ္တဲ့ လုပ္ငန္းစဥ္ကိုေတာ့ က်ေနာ္တို႔ ေရွ႕မွာေလ့လာခဲ့ၿပီးျဖစ္တဲ့ Fast Image Processing ေလ့က်င့္ခန္းအတိုင္း Detect လုပ္ထားပါတရ္။ နားမလည္ေသးတဲ့ မိတ္ေဆြတို႔အတြက္ ေရွ႕သင္ခန္းစာေတြကို ျပန္ဖတ္ေပးပါလို႔ တိုက္တြန္းပါရေစ။ R, G, B Brightness Value အတိုး/အေလွ်ာ့ လုပ္သြားတဲ့ပုံကိုေတာ့ က်ေနာ္ အေပၚမွာ ဥပမာနဲ႔ အေသစိတ္ရွင္းျပခဲ့ပါတရ္။ Coding မွာ ခက္ခဲတာ ဘာမွမပါလို႔ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
ဒါကေတာ့ Calling Method ပံုစံပါ။ if()statement နဲ႔စစ္ထားတာကေတာ့ Processing လုပ္မရ္႕ Image ကုိဆြဲတင္ၿပီး ရွိ/မရွိ သိခ်င္လို႔ပါ။ မိတ္ေဆြတို႔ အားလံုးကို ၿခံဳငံုနားလည္သြားေအာင္ ေအာက္မွာ Coding အျပည့္အစံုကို ေလ့လာႏိုင္ပါတရ္ဗ်။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Change Color Image to Grayscale Image

Posted by ေတဇာလင္း Friday, 17 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Color Image တစ္ခုကို Grayscale Image ပံုစံသို႔ ဘရ္လိုေျပာင္းလဲ ယူႏိုင္မလဲဆိုတာေလးနဲ႔ ပါတ္သတ္ၿပီး ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
ေရွ႕ Black & White ေျပာင္းတဲ့ ေလ့က်င့္ခန္းမွာေတာ့ Grayscale Image နဲ႔ Black & White Image ကြဲျပားတရ္ဆိုတာကို က်ေနာ္ မွတ္ခ်က္ကေလးနဲ႔ ေျပာခဲ့ပါတရ္။ တခ်ိဳ႕က Grayscale Image ကို Black & White Image လို႔ မွားေခၚတတ္ၾကလို႔ပါ။ Black & White Image ဆုိတာက Image တစ္ခုလံုးမွာ အျဖဴ၊ အမဲ Color ႏွစ္မ်ိဳးတည္းနဲ႔ ဖြဲ႔စည္းထားတဲ့ Image ကိုဆိုလိုတာပါ။ Grayscale ကေတာ့ ဒီလိုမဟုတ္ပါဘူး။ Pixel တစ္ခုထဲမွာေတာ့ RGB တူညီတဲ့ Color range ရွိရပါ့မရ္။ Pixel တစ္ခုနဲ႔ တစ္ခုကေတာ့ Color range တူစရာမလိုပါဘူး။ ဥပမာအေနနဲ႔...
first_Pixel = RBG(2, 2, 2);
second_Pixel = RGB(241, 241, 241);
-----
-----
Last_Pixel = RGB(126, 126, 126);
စသည္ျဖစ္ေပါ့။ Color range အနည္း၊ အမ်ားေပၚမူတည္ၿပီး light gray and dark gray ဆိုၿပီး Pixel တစ္ခုနဲ႔တစ္ခု ကြာသြားပါလိမ့္မရ္။ Image တစ္ခုကို Grayscale ေျပာင္းလဲတဲ့အခါမွာေတာ့ က်ေနာ္တို႔ နည္းလမ္း(၃)ခုကိုအသံုးျပဳႏိုင္ပါတရ္။ ၄င္း နည္းလမ္းေတြကေတာ့...
Grayscale (Average Method)
Grayscale (Lightness Method)
Grayscale (Luminosity Method)
တို႔ပဲျဖစ္ပါတရ္။
Average Method // AverageColor = (R + G + B) / 3;
ဒီ Method ကေတာ့ ရိုးရွင္းပါတရ္။ Pixel တစ္ခုကို Detect လုပ္ၿပီး R, G, B Color Value ေတြကို ဆြဲထုတ္ပါတရ္။ ေနာက္ ၄င္း R, G, B Color သံုးခုကိုေပါင္းၿပီး အေရအတြက္နဲ႔ ျပန္စားကာ Average Color တန္ဖိုးကို တြက္ယူပါတရ္။ ေနာက္ဆံုးအဆင့္အေနနဲ႔ ရရွိလာတဲ့ Average Color တန္ဖိုးကို Pixel ရဲ႕ မူလ R, G, B Color တန္ဖိုးေတြ ေနရာမွာ အစားထိုးလိုက္တာပါ။ ဒီနည္းအတိုင္း last Pixel အထိ အလုပ္လုပ္ၿပီး Grayscale Image တစ္ခုအျဖစ္ ေျပာင္းလဲယူလိုက္ တာပဲျဖစ္ပါတရ္။

Lightness Method // LightnessColor = (Max(R, G, B) + Min(R, G, B)) / 2;
ဒီေကာင္ကေတာ့ ပထမဦးဆံုး Pixel တစ္ခုကို Detect လုပ္ၿပီး R, G, B Color Value ေတြကိုဆြဲထုတ္ပါတရ္။ ေနာက္ ၄င္း R, G, B Color Value ေတြထဲကမွ Maximun ကိန္းနဲ႔ Minimum ကိန္းကို ရွာပါတရ္။ ေနာက္တစ္ဆင့္မွာေတာ့ ၄င္း Max and Min ကိန္းႏွစ္လုံးကိုေပါင္းၿပီး 2 နဲ႔ျပန္စားကာ Average Lightness Color ကို တြက္ယူပါတရ္။ ေနာက္ဆံုးအဆင့္အေနနဲ႔ ရရွိလာတဲ့ Average Color တန္ဖိုးကို Pixel ရဲ႕ မူလ R, G, B Color တန္ဖိုးေတြ ေနရာမွာ ျပန္အစားထိုးလိုက္တာပါ။ ဒီနည္းအတိုင္း last Pixel အထိ အလုပ္လုပ္ၿပီး Grayscale Image တစ္ခုအျဖစ္ ေျပာင္းလဲယူလိုက္တာပဲျဖစ္ပါတရ္။

Luminosity Method // LuminosityColor = 0.21 R + 0.72 G + 0.07 B;
ဒီ Mehtod ကလည္း ပထမဦးဆံုး Pixel တစ္ခုကို Detect လုပ္ၿပီး R, G, B Color Value ေတြကိုဆြဲထုတ္ပါတရ္။ ရရွိလာတဲ့ R တန္ဖိုးကို 0.21 နဲ႔ေျမွာက္၊ G တန္ဖိုးကို 0.72 နဲ႔ေျမွာက္၊ B တန္ဖိုးကို 0.07 နဲ႔ေျမွာက္ပါတရ္။ ၿပီးရင္ေတာ့ အားလံုးကို ျပန္ေပါင္းၿပီး Pixel ရဲ႕ မူလ R, G, B Color တန္ဖိုးေတြ ေနရာမွာ ျပန္အစားထိုးလိုက္တာပါ။ ဒီနည္းအတိုင္း last Pixel အထိ အလုပ္လုပ္ခိုင္းၿပီး Grayscale Image တစ္ခုအျဖစ္ ေျပာင္းလဲယူလိုက္တာပဲျဖစ္ပါတရ္။ ကဲ... ဒီေလာက္ဆိုရင္ေတာ့ Grayscale ေျပာင္းလဲယူႏိုင္တဲ့ method သံုးခုကို ၄င္းတို႔ရဲ႕ Formula နဲ႔အတူ သိၿပီ လို႔ ထင္ပါတရ္။ က်ေနာ္တို႔ GUI ေဖာက္ Coding ေရးၿပီး လက္ေတြ႔ေလ့လာၾကည့္ရေအာင္။ ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(1)ခု၊ PictureBox(2)ခုနဲ႔ comboBox(1)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုေဖာ္ ဖန္တီးႏိုင္ပါတရ္ဗ်။
ဒီေန႔ ေလ့က်င့္ခန္းမွာေတာ့ Grayscale Processing အတြက္ ComboBox ကိုသံုးထားပါတရ္။ ComboBox ရဲ႕ Index အခ်ိန္းအေျပာင္းေပၚမူတည္ၿပီး Grayscale Method ေျပာင္းလဲ လုပ္ေဆာင္သြားမွာျဖစ္ပါတရ္။ ComboBox ကို D-Click ေပးၿပီး ေအာက္က Method ေလးကို ေရးယူလိုက္ပါဗ်ာ။ Method ကိုေတာ့ Processing လုပ္မရ္႕ Image နဲ႔ Method Changing အတြက္ Index Value ကုိ Parameter Passing လုပ္ထားပါတရ္။ Pixel Detection လုပ္တဲ့ လုပ္ငန္းစဥ္ကိုေတာ့ က်ေနာ္တို႔ ေရွ႕မွာေလ့လာခဲ့ၿပီးျဖစ္တဲ့ Fast Image Processing ေလ့က်င့္ခန္းအတိုင္း Detect လုပ္ထားပါတရ္။ နားမလည္ေသးတဲ့ မိတ္ေဆြတို႔အတြက္ ေရွ႕သင္ခန္းစာေတြကို ျပန္ဖတ္ေပးပါလို႔ တိုက္တြန္းပါရေစ။ Average, Lightness, Luminosity Method ေတြရဲ႕ အလုပ္လုပ္ပုံကိုေတာ့ က်ေနာ္ အေပၚမွာ အေသစိတ္ရွင္းျပခဲ့ပါတရ္။ Coding မွာ ခက္ခဲတာ ဘာမွမပါလို႔ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။ ဒါကေတာ့ Calling Method ပံုစံပါ။ if()statement နဲ႔စစ္ထားတာကေတာ့ Processing လုပ္မရ္႕ Image ကုိဆြဲတင္ၿပီး ရွိ/မရွိနဲ႔ ComboBox မွာ Processing လုပ္မရ္႔ Method ကို ေရြးခ်ယ္ၿပီးသား ရွိ/မရွိကို သိခ်င္လို႔ပါ။
မိတ္ေဆြတို႔ အားလံုးကို ၿခံဳငံုနားလည္သြားေအာင္ ေအာက္မွာ Coding အျပည့္အစံုကို ေလ့လာႏိုင္ပါတရ္ဗ်။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Change Color Image to Black & White Image

Posted by ေတဇာလင္း Thursday, 16 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Color Image တစ္ခုကို Black & White ပံုစံသို႔ ဘရ္လိုေျပာင္းလဲ ယူႏိုင္မလဲဆိုတာေလးနဲ႔ ပါတ္သတ္ၿပီး ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
က်ေနာ္တို႔ ဒီေန႔ ေလ့က်င့္ခန္းေလးကို မေလ့လာမွီ Ditigal Image တစ္ခုရဲ႕ အၾကမ္းဖ်ဥ္း ဖြဲ႔စည္းပံုနဲ႔ သေဘာတရားကို ၾကည့္မရ္ဆိုရင္ သိခဲ့ၿပီးသားအတိုင္းပါပဲ... Image တစ္ခုဟာ 2-Dimension ပံုစံ Pixel ေတြနဲ႔ ဖြဲ႔စည္းထားပါတရ္။ Pixel တစ္ခုစီတိုင္းမွာေတာ့ အေျခခံအက်ဆံုး Red, Green, Blue and Alpha ဆိုတဲ့ Color တန္ဖိုးေတြရွိပါတရ္။ ဒီ Color တန္ဖိုး အခ်ိန္းအေျပာင္းေပၚမူတည္ၿပီး Pixel တစ္ခုစီတိုင္းမွာ Secondly Color တစ္ခုစီျဖစ္လာၿပီး ရုပ္လံုးေပၚကာ က်ေနာ္တို႔ ျမင္ကြင္းထဲကို ေရာက္လာတာပဲျဖစ္ပါတရ္။ ယင္းဆိုရင္ျဖင့္ Pixel တစ္ခုစီတိုင္းမွာရွိတဲ့ Color တန္ဖိုးေတြကို Black သို႔မဟုတ္ White အျဖစ္ ေျပာင္းလဲေပးႏိုင္မွသာ က်ေနာ္တို႔ လိုခ်င္ေနတဲ့ Black & White Image တစ္ခုကို ရရွိပါလိမ့္မရ္။
ဒီေတာ့ က်ေနာ္တို႔အေနနဲ႔ RGB Color Channel ရဲ႕ ဘရ္တန္ဖိုးေတြက Black ျဖစ္တရ္၊ ဘရ္တန္ဖိုးေတြက White ျဖစ္မရ္ဆုိတာကို သိဖို႔လိုအပ္လာပါၿပီ။ မခက္ခဲပါဘူးဗ်ာ။ Color တန္ဖိုးရဲ႕ lower bound ျဖစ္တဲ့ Zero(0) ဟာ Black Color ျဖစ္ၿပီး upper bound ျဖစ္တဲ့ 255 ဟာ White Color ျဖစ္ပါတရ္ (Color Channel တစ္ခုဟာ 0 to 255 ရွိတရ္ဆိုတာေတာ့ သိၾကမရ္ထင္ပါတရ္)။ ဆိုလိုတာကေတာ့ RBG(0, 0, 0) ဟာ Black Color ျဖစ္တရ္။ RGB(255, 255, 255) ဟာ White Color ျဖစ္တရ္လို႔ ေျပာတာပါ။
ကိုရင္ေမာင္ေရ... Color တန္ဖိုးေတြကို Black(0) ျဖစ္ျဖစ္၊ White(255) ျဖစ္ျဖစ္ ေျပာင္းလဲရမွာေတာ့ ဟုတ္ပါၿပီ။ Pixel ကို Detect လုပ္တဲ့အခါမွာ 0 to 255 ၾကား ဘာျဖစ္လာမရ္မွန္းမသိတဲ့ Color တန္ဖိုးေတြ ရမွာေလ။ ဒါကို က်ေနာ္တို႔က ဘရ္ဟာကို Black ေျပာင္းၿပီး ဘရ္ဟာကို White ေျပာင္းယူမွာလဲလို႔ ေမးဖို႔ရွိလာပါတရ္။ ဒီအေမးကိုေတာ့ က်ေနာ္တို႔အေနနဲ႔... ဒီ Algorithm အတြက္ တိတိက်က် သတ္မွတ္ထားတာမရွိပါဘူး။ User ရဲ႕ လိုအပ္ခ်က္အရ Threshold value တစ္ခုထားၿပီး ပိုင္းျခားလိုက္ပါလို႔ ေျဖရမွာပါပဲ။ Threshold Value ဆိုလို႔ ေခါင္းရႈပ္မသြားပါနဲ႔။ 0 to 255 ၾကား တန္ဖိုးတစ္ခုခုကို key အျဖစ္ အေသယူလိုက္တာပါ။ Detect ရရွိတဲ့ တန္ဖိုးဟာ ယင္း key နဲ႔ငယ္ရင္ Black ေျပာင္း၊ ႀကီးရင္ White အျဖစ္ေျပာင္းပါလို႔ ခိုင္းလိုက္တာပါ။ အမ်ားစုကေတာ့ Color Rage (0 to 255) ရဲ႕ တ၀တ္ျဖစ္တဲ့ 127 ကို Threshold Value ထားၿပီး Black & White Image အျဖစ္ ေျပာင္းယူၾကပါတရ္။ နားလည္ၾကမရ္ ထင္ပါတရ္ဗ်။
ကဲ... က်ေနာ္တို႔ Processing ရဲ႕ သေဘာတရားကို သိၿပီဆိုရင္ေတာ့ GUI ေလးေဖာက္ၿပီး Coding ေလးနဲ႔ လက္ေတြ႔ ေလ့လာၾကည့္ၾကရေအာင္။ ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(1)ခု၊ Label(1)ခု၊ PictureBox(2)ခုနဲ႔ TrackBar(1)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုေဖာ္ ဖန္တီးႏိုင္ပါတရ္ဗ်။
ဒီေန႔ ေလ့က်င့္ခန္းမွာေတာ့ Black & White Processing အတြက္ သီးသန္႔ Button မထည့္ေတာ့ပဲ TrackBar ရဲ႕ Scroll_Event ထဲက တိုက္ရိုက္ Processing လွမ္းလုပ္တဲ့ ပံုစံေလးနဲ႔ ေလ့လာၾကည့္သြားပါ့မရ္။ ဒီေတာ့ TrackBar Value ေျပာင္းလဲမႈရွိတိုင္း Black & White Processing ေျပာင္းလဲမႈျဖစ္မွာ ျဖစ္ပါတရ္။ TrackBar ကို D-Click ေပးၿပီး ေအာက္က Method ေလးကို ေရးယူလိုက္ပါဗ်ာ။ Method ကိုေတာ့ Processing လုပ္မရ္႕ Image နဲ႔ Threshold Value ကုိ Parameter Passing လုပ္ထားပါတရ္။ Pixel Detection လုပ္တဲ့ လုပ္ငန္းစဥ္ကိုေတာ့ က်ေနာ္တို႔ ေရွ႕မွာေလ့လာခဲ့ၿပီးျဖစ္တဲ့ Fast Image Processing ေလ့က်င့္ခန္းအတိုင္း Detect လုပ္ထားပါတရ္။ နားမလည္ေသးတဲ့ မိတ္ေဆြတို႔အတြက္ ေရွ႕သင္ခန္းစာေတြကို ျပန္ဖတ္ေပးပါလို႔ တိုက္တြန္းပါရေစ။ ဒီမွာ Black & White အတြက္ ထူးျခားသြားတာကေတာ့ Pixel တစ္ကြက္ခ်င္းစီမွာ ရွိေနတဲ့ R, G, B Color တန္ဖုိး(၃)ခုကို ေပါင္းၿပီး အေရအတြက္နဲ႔ ျပန္စားကာ Average Color တန္ဖိုးကို ရွာယူလိုက္တာပါပဲ။ က်န္တာကေတာ့ က်ေနာ္ အေပၚမွာ ေဆြးေႏြးခဲ့ၿပီးတဲ့အတိုင္းပဲ ရလာတဲ့ averageColor တန္ဖိုးကို Threshold Value နဲ႔ ႏႈိင္းယွဥ္ပါတရ္။ averageColor ကႀကီးေနရင္ ယင္း Pixel ကြက္ရဲ႕ R, G, B Color တန္ဖိုးေတြကို 255 ေတြေပးၿပီး အျဖဴေရာင္ Pixel ကြက္အျဖစ္ေျပာင္းလဲယူပါတရ္။ ငယ္ခဲ့ရင္ေတာ့ 0 ေတြေပးၿပီး အနက္ေရာင္ Pixel ကြက္အျဖစ္ ဖန္တီးယူလိုက္တာပါ။ အရမ္း ရိုးရွင္းၿပီး လြယ္ကူလြန္းပါတရ္။ ဒါကေတာ့ Calling Method ပံုစံပါ။ ဘရ္ေလာက္ Threshold Value နဲ႔ Processing လုပ္ထားတရ္ဆိုတာကို ျပဖို႔ Label ကိုသံုးထားပါတရ္။ if()statement နဲ႔စစ္ထားတာကေတာ့ Processing လုပ္မရ္႕ Image ကုိဆြဲတင္ၿပီး ရွိ/မရွိကို သိခ်င္လို႔ပါ။
မိတ္ေဆြတို႔ အားလံုးကို ၿခံဳငံုနားလည္သြားေအာင္ ေအာက္မွာ Coding အျပည့္အစံုကို ေလ့လာႏိုင္ပါတရ္ဗ်။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Rotate and Flip Image using RotateFlip()Method

Posted by ေတဇာလင္း Tuesday, 14 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Image တစ္ခုကို Rotate and Flip ပံုစံအမ်ိဳးမ်ိဳးနဲ႔ ဘရ္လိုဆြဲယူ ၾကည့္ႏိုင္မလဲဆိုတာေလးန႔ဲ ပါတ္သတ္ၿပီး ေလ့လာၾကည့္ပါ့မရ္။ နည္းလမ္းေပါင္းစံု ရွိတဲ့အထဲကေနၿပီ အလြရ္ကူဆံုးနည္းလမ္းျဖစ္တဲ့ System.Drawing; ေအာက္က RotateFlip()Method ကိုအသံုးျပဳၿပီး ဖန္တီးယူႏိုင္တာေလးကို ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။ က်ေနာ္တို႔ အသံုးျပဳႏိုင္တဲ့ RotateFlipType (16)မ်ိဳးရွိပါတရ္။ ရွင္းလင္းခ်က္ေတြကိုေတာ့ ေအာက္က Table မွာ ၾကည့္ႏိုင္ပါတရ္။
Drawing Library က အသင့္ေပးထားတဲ့ Method ကိုေခၚသံုးမွာျဖစ္လို႔ ဒီေန႔ ေလ့က်င့္ခန္းက လြရ္တရ္လို႔ ထင္ရပါလိမ့္မရ္။ ဒါေပမရ္႕ Image Control and Processing ဘက္ကို ေလ့လာေနတဲ့ သူေတြအတြက္ တစ္ဘက္တစ္လမ္းက အေထာက္အကူျဖစ္ႏိုင္လိမ့္မရ္လို႔ေတာ့ ထင္ပါတရ္။ ေနာက္ပိုင္း အဆင့္ျမင့္သင္ခန္းစာေတြၾကရင္ေတာ့ ဒီ Flip and Rotation Method ေတြကို ကိုယ္တိုင္ ဘရ္လိုဖန္တီးယူႏိုင္မလဲဆိုတာနဲ႔ ပါတ္သတ္ၿပီး Graphic နဲ႔ျဖစ္ေစ၊ Pixel Detection ပံုစံနဲ႔ျဖစ္ေစ က်ေနာ္ ထပ္ေဆြးေႏြးေပးပါ့မရ္ဗ်။ ဒီေန႔ေတာ့ သေဘာတရားနဲ႔ Result ကို ကၽြမ္း၀င္သြားေအာင္ လြရ္လြရ္ကူကူပဲ ေလ့လာၾကည့္ၾကပါ့မရ္။
ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(1)ခု၊ PictureBox(2)ခုနဲ႔ ComboBox(1)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုစံေဖာ္ႏိုင္ပါတရ္။
ဒီေန႔ ေလ့က်င့္ခန္းကိုေတာ့ အဆင့္(၃)ဆင့္နဲ႔ ေလ့လာၾကည့္ပါ့မရ္။ ပထမအဆင့္ကေတာ့ Form_Load မွာ System.Drawing; Library ေအာက္မွာ Enumation အေနနဲ႔ ရွိေနၿပီးသား RotateFlipType ေတြကို ComboBox ထဲသို႔ ဆြဲတင္ယူမွာျဖစ္ပါတရ္။ ဒီအတြက္ LoadFlipType() Method ဖန္တီးပံုေလးနဲ႔ Form_Load မွာေခၚယူပံုေလးကို ေအာက္မွာ ေလ့လာၾကည့္ပါ့မရ္။ LoadFlipType()Method မွာေတာ့ Parameter အျဖစ္ ComboBox ကို Passing လုပ္ထားပါတရ္။ Coding စစခ်င္းမွာ Enum.GetNames() Method ကိုအသံုးျပဳၿပီး System.Drawing; Libray ထဲက Enumation Type အေနနဲ႔ သိမ္းထားေသား RotateFlipType ေတြကို Scan ဖတ္ယူပါတရ္(ဒီနည္းအတိုင္းပဲ အျခားေသာ Enumation Type ေတြကိုလည္း ဆြဲယူႏုိင္ပါတရ္ဗ်)။ ဒီမွာ Array တစ္ခုခုထဲကို ထည့္ထားလို႔ရပါတရ္။ က်ေနာ္ကေတာ့ var Type ကိုသံုးထားပါတရ္။ ေနာက္တစ္ေၾကာင္းမွာေတာ့ Scan ဖတ္လို႔ရရွိလာတဲ့ Flip Type ေတြကို Loop ပါတ္ၿပီး string Data ေတြအျဖစ္ ComboBox ထဲသို႔ Add လိုက္တာပဲျဖစ္ပါတရ္။ အေပၚက Form_Load ရဲ႕ Calling Method မွာေတာ့ က်ေနာ္တို႔ Flip Type ေတြကို ေဖာ္ျပေစခ်င္တဲ့ ComboBox ကို Parameter ေခၚေပးလိုက္ယံုပါပဲဗ်။ ဒါဆိုရင္ေတာ့ Form_Load တတ္ၿပီးတဲ့အခ်ိန္မွာ ေအာက္ကပံုအတိုင္း ComboBox ထဲမွာ Flip Type ေတြေရာက္ေနတာ ေတြ႔ရပါလိမ့္မရ္။
ခက္ခက္ခဲခဲမပါလို႔ နားလည္ၾကလိမ့္မရ္လို႔ ထင္ပါတရ္ဗ်။ ဒုတိယအဆင့္ကို ဆက္ေလ့လာၾကည့္ပါ့မရ္။ ဒီအဆင့္ကေတာ့ picOriginalImg PictureBox ထဲသို႔ Image ဆြဲတင္တဲ့အပိုင္းပါ။ PictureBox ထဲသို႔ Image ဆြဲတင္တာကိုေတာ့ ေရွ႕မွာ ေလ့လာခဲ့ၿပီးျဖစ္ၾကတဲ့ ေလ့က်င့္ခန္းတိုင္းမွာ ပါေနလို႔ က်ေနာ္အေသးစိတ္မရွင္းေတာ့ပါဘူး။
ေနာက္ဆံုးအဆင့္ကေတာ့ ComboBox ရဲ႕ Index Change မွာ ေရြးခ်ယ္လိုက္တဲ့ Action အေပၚမူတည္ၿပီး Flip and Rotation Process ကိုလုပ္ၿပီး picResultImg PictureBox မွာ ေဖာ္ျပေပးဖို႔ပါ။ ဒီအတြက္ cbFlipType ComboBox ကို D_Click ေပးၿပီး SelectedIndexChanged Event မွာ ေအာက္ပါ Calling ပံုစံနဲ႔ Method ခြဲေရးတဲ့ပံုစံေလးကို ေရးယူလုိက္ပါဗ်ာ။ Calling Method ပံုစံကေတာ့ ရွင္းပါတရ္။ စစခ်င္းမွာ if()statement နဲ႔ Processing လုပ္ခ်င္တဲ့ Image ဆြဲတင္ၿပီးသား ရွိ/မရွိကို စစ္ပါတရ္။ Image Loading မလုပ္ရေသးဘူးဆိုရင္ေတာ့ FlipImage()Method ကို လွမ္းေခၚမွာ မဟုတ္ပါဘူးဗ်။ Image လည္း Loading ရွိၿပီ၊ ComboBox မွာလည္း Action တစ္ခုခုကို ေရြးၿပီဆိုရင္ေတာ့ ေအာက္က FlipImage()Method ကို လွမ္းေခၚပါလိမ့္မရ္။ FlipImage()Method မွာေတာ့ Parameter အျဖစ္ Image တစ္ခုနဲ႔ string တစ္ခုကို Passing လုပ္ထားပါတရ္။ ပထမ parameter ကေတာ့ processing လုပ္ခ်င္တဲ့ Image ပါ။ ဒုတိယကေတာ့ ေျပာင္းလဲယူခ်င္တဲ့ Rotate and Flip Type ေပါ့။ အတြင္းပိုင္း အလုပ္လုပ္သြားတဲ့ ပံုစံကေတာ့ က်ေနာ္တို႔ ေလ့လာေနၾက ပံုစံအတိုင္းပါပဲ။ ေရာက္လာတဲ့ Image ကို Bitmap အျဖစ္ Clone ပြားယူပါတရ္။ ဒုတိယ cmd line ကေတာ့ string အေနနဲ႔ ပို႔လိုက္တဲ့ RotateFlipType စာသားကို RotateFlip()Method ကနားလည္တဲ့ RotateFlipType အျဖစ္ ေျပာင္းလဲယူတာပါ။ ရွင္းျပရခက္တရ္ဗ်။ ဒါေပမဲ့ ၾကည့္လိုက္တာနဲ႔ နားလည္ၾကမရ္ ထင္ပါတရ္။ ဒီအဆင့္ကို ေရာက္ၿပီဆိုရင္ေတာ့ String အေနနဲ႔ Passing ၀င္လာတဲ့ RotateFlipType ေတြဟာ RotateFlip()Method ကနားလည္တဲ့ RotateFlipType အစစ္ျဖစ္သြားပါၿပီ။ ဒါဆိုရင္ေတာ့ တတိယ cmd line အတိုင္း က်ေနာ္တို႔ Clone ပြားယူထားေသာ Image ကို RotateFlip() Method ကိုအသံုးျပဳၿပီး Processing လုပ္ေပးပါလို႔ ခိုင္းလိုက္ယံုပါပဲ။ ေနာက္ဆံုးအဆင့္ကေတာ့ Processing လုပ္ၿပီသား Image ကို ျပန္လည္ေဖာ္ေျပေပးႏိုင္ရန္ Call Method ဆီသို႔ Return ျပန္ေပးလိုက္တာပဲ ျဖစ္ပါတရ္ဗ်ာ။ ပံုမွာ က်ေနာ္ ဥပမာအေနနဲ႔ Rotate180FlipY ဆိုၿပီး ေျပာင္းျပထားပါတရ္ဗ်။
ပိုၿပီးနားလည္သြားေအာင္ Coding အျပည့္အစံုကို ေအာက္မွာ ေလ့လာၾကည့္လိုက္ၾကပါအံုးဗ်ာ။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Zoom In/Out Image using Graphics

Posted by ေတဇာလင္း Thursday, 9 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Image တစ္ခုကို ZoomIn, ZoomOut ပံုစံျဖစ္ ဘရ္လိုဆြဲယူ ၾကည့္ႏိုင္မလဲဆိုတာေလးနဲ႔ ပါတ္သတ္ၿပီး ေလ့လာၾကည့္ပါ့မရ္။ နည္းလမ္းေပါင္းစံု ရွိတဲ့အထဲကေနၿပီ အလြရ္ကူဆံုးနည္းလမ္းျဖစ္တဲ့ Graphic ဆြဲၿပီး ဖန္တီးယူတဲ့ နည္းလမ္းကိုပဲ အသံုးျပဳၿပီး ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ GUI တည္ေဆာက္ျခင္းအပိုင္းမွာေတာ့ က်ေနာ္ Button(1)ခု၊ PictureBox(1)ခု၊ Panel(1)ခု၊ TrackBar(1)ခုနဲ႔ Label(1)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္က Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုစံေဖာ္ႏိုင္ပါတရ္။
ဒီေန႔ ေလ့က်င့္ခန္းမွာေတာ့ Zoom Processing အတြက္ သီးသန္႔ Button မထည့္ေတာ့ပဲ TrackBar ရဲ႕ Scroll_Event ထဲက တိုက္ရိုက္ Processing လွမ္းလုပ္တဲ့ ပံုစံေလးနဲ႔ ေလ့လာၾကည့္သြားပါ့မရ္။ ဒီေတာ့ TrackBar Value ေျပာင္းလဲမႈရွိတိုင္း Zoom Processing ေျပာင္းလဲမႈျဖစ္မွာ ျဖစ္ပါတရ္။ Coding ကို တစ္ဆင့္ခ်င္းစီ ေလ့လာၾကည့္မရ္။ ဒါကေတာ့ က်ေနာ္တို႔ Load Image Button ကို အသံုးျပဳၿပီး PictureBox ေပၚသို႔ Image ဆြဲတင္တဲ့ေနရာမွာ Zoom Processing အတြက္ လိုအပ္ခ်က္မ်ားကို Initial သတ္မွတ္ေပးထားတာပါ။ Global Variable အျဖစ္ colneImg ဆိုၿပီး Processing လုပ္ေနစဥ္အတြင္းမွာ Image ကို သိုေလွာင္ရန္ Image Type တစ္ခုကို ဖန္တီးပါတရ္။ ၿပီးရင္ေတာ့ PictureBox ေပၚသို႔ Image ဆြဲတင္ၿပီးတဲ့အခ်ိန္မွာ ၄င္း Variable ထဲသို႔ Clone ပြားယူ Assign လုပ္လိုက္ပါတရ္။ ဆိုလိုတဲ့ သေဘာကေတာ့ ေနာက္ပိုင္း Processing လုပ္ငန္းစဥ္အတြင္း မူရင္း Image ကိုမထိပဲ ယခု Clone ပြားယူထားေသာ Image နဲ႔သာ Processing လုပ္ပါလို႔ ေျပာလိုက္တာပါ။ PictureBox ရဲ႕ Size ကို CloneImg ရဲ႕ Size အတိုင္း ေျပာင္းလဲလိုက္တာ ကေတာ့ ဆြဲတင္လိုက္ေသာ Image ရဲ႕ Width and Height အတိုင္း PictureBox က လိုက္ၿပီး Fixed ျဖစ္သြားေအာင္ပါ။ TrackBar ကို Initial Value = 50 ေပးထားတာကေတာ့ Zoom In/Out အတြက္ TrackBar ကို စမွတ္ 50 မွာ Zero Line ခ်လိုက္တာပါ။ ဒါမွ ကနဦး ဆြဲတင္လိုက္ေသာ Image ဟာ 50(0%)မွာ ေဖာ္ျပၿပီး 50 ေအာက္ငယ္သြားရင္ ဘရ္ေလာက္ % ထိ ZoomOut ျဖစ္သြားလဲဆိုတဲ့ ZoomOut Process လုပ္္ကာ 50 ထက္မ်ားသြားရင္ေတာ့ ဘရ္ေလာက္ % ထိ ZoomIn ျဖစ္သြားလဲဆိုတဲ့ ZoomIn Process ကိုလုပ္ပါလို႔ ခိုင္းလို႔ရမွာပါ။ နားလည္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္။
Zoom In/Out Method ကို ဆက္ေလ့လာၾကည့္ပါ့မရ္။ tbZoomValue ကို D_Click ေပးၿပီး TrackBar ရဲ႕ Scroll_Event ထဲမွာ ေအာက္ပါ Coding ကိုေရးယူလိုက္ပါဗ်ာ။ အနည္းငရ္ရွင္းျပပါ့မရ္။ စစခ်င္းမွာ if()Statement နဲ႔ Zoom Processing လုပ္ခ်င္တဲ့ Image ကို PictureBox ေပၚသို႔ ဆြဲတင္ၿပီးသား ရွိ/မရွိ တနည္းအားျဖင့္ Processing လုပ္ဖို႔ Clone Image ရွိ/မရွိ စစ္ေဆးပါတရ္။ Image မဆြဲတင္ရေသးဘူး ဆိုရင္ေတာ့ Zoom Function အလုပ္လုပ္မွာ မဟုတ္ပါဘူးဗ်ာ။ ဒုတိယ cmd line ကေတာ့ ဘရ္ေလာက္ Zoom In/Out ျဖစ္ေနလဲဆိုတဲ့ Information ကို အသံုးျပဳသူကို ျပေစခ်င္လို႔ ထည့္ထားတာပါ။ TrackBar Value က 50 ေအာက္ငရ္ရင္ အႏုတ္တန္ဖိုးျပမွာျဖစ္ၿပီး 50 ထက္ႀကီးရင္ေတာ့ အေပါင္းတန္ဖိုး ျပေပးမွာျဖစ္ပါတရ္။ ေနာက္တစ္ေၾကာင္းမွာေတာ့ if()statement နဲ႔ zoom တန္ဖိုး (သို႔မဟုတ္) TrackBar Value ဟာ 50 နဲ႔ ညီလား၊ ငယ္လားလို႔ ထပ္စစ္ပါတရ္။ Connection မွန္ရင္ေတာ့ Zoom Out Processing အတြက္ ေအာက္က အလုပ္ကို ဆက္လုပ္ပါလိမ့္မရ္။ ဒီမွာေတာ့ Image ရဲ႕ Width and Height ကို ZoomOut ေၾကာင့္ ေျပာင္းလဲသြားေသာ Width and Height အတိုင္း Rebuild ျပန္လုပ္ေပးဖို႔အတြက္ reWidth နဲ႔ reHeight ဆိုၿပီး တြက္ထုတ္ယူထားပါတရ္။ တြက္ခ်က္မႈကိုေတာ့ အေရာင္းဆိုင္ေတြမွာ Discount တြက္တဲ့ ပံုေသနည္းအတိုင္း စဥ္းစားၿပီး တြက္ယူထားတာပါ။ ဥပမာ - က်သင့္ေငြ 1000 က်ေသာ ပစၥည္းတစ္ခုကို 5% Discount ေပးမရ္ဆိုပါစို႔။ ဒါဆို...
Net Amount = က်သင့္ေငြ - ((က်သင့္ေငြ x Discount) / 100);
ဒီ Formula အတိုင္း တြက္ယူႏိုင္ပါတရ္။ ဒီေတာ့...
Net Amount = 1000 – ((1000 x 5) /100); = 950 က်ပ္ က်သင့္မွာျဖစ္ပါတရ္။
ဒီနည္းလမ္း အတိုင္းပါပဲ။ Zoom Out ေၾကာင့္ ေျပာင္းလဲေပးရမရ္႕ Imag ရဲ႕ Size ကို တြက္ယူလိုက္တာပါ။ 50 ထဲက tbZoomValue.Value ကို ျပန္ႏုတ္ထားတာကေတာ့ ကနဦးတည္းက မူရင္း Image Size ကို 50 မွာ Zero Line ခ်ခဲ့လို႔ပါ။ ဒီပံုစံအတိုင္း က်ေနာ္ 5% ေလွ်ာ့ခ်တဲ့ ZoomOut တစ္ခုကို တြက္ျပပါ့မရ္။ ဥပမာ - က်ေနာ္တို႔ Image Size က 1024x768 ရွိတရ္ဆိုပါစို႔။ သူ႔ကိုမွ 5% ZoomOut လုပ္မရ္ေပါ့။ ဒီေတာ့ ပံုေသနည္းထဲကို ျဖတ္ၾကည့္ပါမရ္။
 
reWidth = cloneImg.Width - ((cloneImg.Width * (50 - tbZoomValue.Value)) / 100);
reWidth = 1024 – ((1024 * (50 - 45))/100);
reWidth = 1024 – ((1024 * 5)/100);
reWidth = 1024 – (5120/100);
reWidth = 1024 – 51;
reWidth = 973;
ဒါဆို Width = 1024 ကို 5% ZoomOut လုပ္တဲ့အခါမွာ ေျပာင္းလဲသြားတဲ့ reWidth = 973 ကို ရရွိပါၿပီ။ က်ေနာ္တို႔ Height ကို ဆက္တြက္ၾကည့္မရ္။
reHeight = cloneImg.Height - ((cloneImg.Height * (50 - tbZoomValue.Value)) / 100);
reHeight = 768 – ((768 * (50 - 45))/100);
reHeight = 768 – ((768 * 5)/100);
reHeight = 768 – (3840/100);
reHeight = 768 – 38;
reHeight = 730;
ဒါဆို Height = 768 ကို 5% ZoomOut လုပ္တဲ့အခါမွာ ေျပာင္းလဲသြားတဲ့ reHeight = 730 ကို ရရွိပါၿပီ။ ဒီေတာ့ 1024x768 ရွိေသာ Image တစ္ခုကို 5% ZoomOut လုပ္ရင္ 973x730 ရရွိမွာပါ။ ဒီနည္းအတိုင္း ရာခိုင္ႏႈန္း(%) သို႔မဟုတ္ TrackBar Value အႏုတ္ဘက္သို႔ ေျပာင္းလဲမူအေပၚ မူတည္ၿပီး ZoomOut Processing အတြက္ Width and Height ေျပာင္းလဲသြားမွာပဲ ျဖစ္ပါတရ္။ ေနာက္တစ္ဆင့္မွာေတာ့ ZoomOut ျဖစ္သြားေသာ Width and Height အတိုင္း Image ကုိ သိုေလွာင္ဖို႔ Bitmap Container တစ္ခု ဖန္တီးလိုက္ပါတရ္။ ၿပီးရင္ေတာ့ ၄င္း Bitmap အတိုင္း Grahic ဆြဲယူပါ့မရ္လို႔ ခိုင္းပါတရ္။ Graphic ဆြဲၿပီးသြားရင္ေတာ့ က်ေနာ္တို႔ ZoomOut Image တစ္ခုရပါၿပီး ဒီေကာင့္ကို မူရင္း Image Viewer ျဖစ္တဲ့ PictureBox ေပၚသို႔ ျပန္ဆြဲတင္ေပးလိုက္ယံုပါပဲဗ်ာ။ PictureBox ရဲ႕ Size ကို Rebuilt လုပ္ထားတာကေတာ့ ေျပာင္းလဲသြားေသာ ZoomOut Image အတိုင္း PictureBox Size ကုိ fixed ျဖစ္ေနေအာင္ပဲျဖစ္ပါတရ္။
ZoomIn အတြက္ တြက္ခ်က္မႈကလည္း ZoomOut ရဲ႕ သေဘာတရားအတိုင္းပါပဲဗ်ာ။ က်ေနာ္အေသးစိတ္ မရွင္းေတာ့ပါဘူး။ ((cloneImg.Width * (tbZoomValue.Value - 50)) / 100) ဒါက Percentage တြက္ယူတဲ့အပိုင္းပါ။ TrackBar Value က 50(Zero Line Value) ထက္ႀကီးသြားမွာျဖစ္လို႔ ျပန္ႏုတ္ေပးျခင္းျဖင့္ ZoomIn လုပ္ေပးမရ္႕ Percentage တန္ဖိုးကို တြက္ယူထားတာပါ။ မူရင္း Width and Height နဲ႔ ျပန္ေပါင္းေပးထားတာကေတာ့ မူလ Image ထက္ တြက္ထုတ္ထားေသာ Percentage အတိုင္း ႀကီးသြားေစခ်င္လို႔ပါ။ ဒီေလာက္ဆိုရင္ေတာ့ Zoom In/Out ကို Percentage နဲ႔ လုပ္ႏိုင္တဲ့ နည္းလမ္းေလးကို နားလည္ႏိုင္ၾကၿပိလို႔ ထင္ပါတရ္။
ပိုၿပီးနားလည္သြားေအာင္ Coding အျပည့္အစံုကို ေအာက္မွာ ေလ့လာၾကည့္လိုက္ၾကပါအံုးဗ်ာ။ Result ကိုေတာ့ ပံုမွာ ၾကည့္ရင္ အရွင္းႀကီး သိႏိုင္ပါလိမ့္မရ္။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

C# - Crop Image in a Ellipse Shape using Graphics

Posted by ေတဇာလင္း Tuesday, 7 February 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Image တစ္ခုကို မိမိႏွစ္သက္ရာေနရာအား Ellipse ပံုစံျဖစ္ ဘရ္လိုျဖတ္ယူႏိုင္မလဲဆိုတာေလးကို ေလ့လာၾကည့္ပါ့မရ္။ နည္းလမ္းေပါင္းစံု ရွိတဲ့အထဲကေနၿပီ အလြရ္ကူဆံုးနည္းလမ္းျဖစ္တဲ့ Graphic Library ေအာက္က DrawImage() Method ကို အသံုးျပဳၿပီး ေလ့လာၾကည့္ပါ့မရ္။ က်ေနာ့္ ေလ့က်င့္ခန္းေတြကေတာ့ စတင္ ေလ့လာသူမ်ား အတြက္သာ ရည္ရြယ္ပါတရ္။ ဒါေၾကာင့္ သိေနၿပီးသား သူမ်ားအေနနဲ႔ နားလည္ေပးၾကဖို႔နဲ႔ က်ေနာ္ရဲ႕ တင္ျပပံု မွားယြင္းတာမ်ားရွိခဲ့ရင္ ျပန္လည္ေထာက္ျပေပးႏိုင္ဖို႔ ေမွ်ာ္လင့္ပါတရ္ဗ်။
ဒါကေတာ့ က်ေနာ္တို႔ Project မွာ အသံုးျပဳမရ္ Library File ေတြပါ။ က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုစံေဖာ္ႏိုင္ပါတရ္။
က်ေနာ္ကေတာ့ ေအာက္ကပံုအတိုင္း ပံုစံခ်ထားပါတရ္ဗ်ာ။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ GUI ကို ႀကိဳက္သလို ပံုစံေဖာ္ႏိုင္ပါတရ္။
ဒီေန႔ ေလ့က်င့္ခန္းမွာေတာ့ Crop Processing အတြက္ သီးသန္႔ Button မထည့္ေတာ့ပဲ picOriginalImg ရဲ႕ Event ေတြကပဲ Processing လွမ္းလုပ္တဲ့ ပံုစံေလးနဲ႔ ေလ့လာၾကည့္သြားပါ့မရ္။ အသံုးျပဳသြားမရ္႕ Event ေတြကေတာ့ MouseDown, MouseMove and MouseUp တို႔ပဲ ျဖစ္ပါတရ္။ MouseDown Event ထဲမွာေတာ့ PictureBox ေပၚသို႔ Left_Click ျဖင့္ Mouse Point ခ် Down/Click ေပးလိုက္တဲ့အခ်ိန္မွာ လုပ္ေစခ်င္တဲ့ အလုပ္ေတြကို ခိုင္းေစႏိုင္ပါတရ္။ MouseMove Event ကေတာ့ Left_Clik ေပးၿပီး Drag ဆြဲတဲ့အခ်ိန္မွာ လုပ္ေစခ်င္တဲ့ အလုပ္ေတြကို ခိုင္းဖို႔ပါ။ MouseUp မွာေတာ့ Mouse Down and Move အလုပ္ ႏွစ္ခုလုပ္ၿပီး ျပန္လႊတ္လိုက္တဲ့အခ်ိန္မွာ လုပ္ေစခ်င္တဲ့ အလုပ္ေတြကို ခိုင္းေစႏိုင္ပါတရ္။ ဒီေန႔ ေလ့က်င့္ခန္းမွာေတာ့ Event သံုးခုလံုးၿပီးမွ Processing တစ္ခု လုပ္တဲ့ပံုစံနဲ႔ ခ်ဥ္းကပ္ထားပါတရ္။
Event တစ္ခုခ်င္းစီထဲက Code ကို အေသးစိတ္ေလ့လာၾကည့္ၾကရေအာင္...။ picOriginalImg ရဲ႕ MouseDown_Event ထဲသို႔ ၀င္၍ ေအာက္ပါ Coding ကိုေရးယူလုိက္ပါဗ်ာ။ Method ရဲ႕ အျပင္ဘက္မွာ Global Variable အျဖစ္ x, y, cropWidth, cropHeight ဆိုၿပီး ေလးခုေၾကျငာထားပါတရ္။ ၄င္း variable ေတြကို ဒီ Event တစ္ခုတည္းကတင္ မဟုတ္ဘဲ အျခားေသာ Event ေတြကပါ ေခၚသံုးႏိုင္ေအာင္လို႔ Global ေၾကျငာထားျခင္းျဖစ္ပါတရ္။ MouseDown_Event ထဲမွာ ခိုင္းထားတဲ့အလုပ္ကေတာ့ ရိုးရွင္းပါတရ္။ စစခ်င္းမွာ if()Statement နဲ႔ Mouse ရဲ႕ Event(Action)ကိုဖမ္းၿပီး Left Click ျဖစ္လား/မျဖစ္လားဆိုၿပီး စစ္ထားပါတရ္။ Left_Click Action ျဖစ္ခဲ့ရင္ေတာ့ က်ေနာ္တို႔ Global ေၾကျငာထားေသာ x, y variable ထဲကို မိတ္ေဆြကို Mouse Down/Click ေပးလိုက္ေသာ X,Y Coordinate ကို လွမ္းထည့္လိုက္ပါတရ္။ ဆိုလိုတာကေတာ့ မိတ္ေဆြတို႔ Crop ရဲ႕ Image ဟာ ဒီ X, Y Coordinate က စပါ့မရ္လို႔ မွတ္ထားခိုင္းလိုက္တာပဲျဖစ္ပါတရ္။ ကာဆာကို Cross သံုးထားတာကေတာ့ Mouse Down and Drag လုပ္ေနတဲ့အခ်ိန္မွာ ကာဆာကို Cross ပံုစံေလး ျပေနေစခ်င္တဲ့အတြက္ေၾကာင့္ပါ။ ဒီေလာက္ဆိုရင္ေတာ့ MouseDown_Event မွာ ခိုင္းေစထားတဲ့အခ်ိန္ေတြကို သိၿပီလို႔ ထင္ပါတရ္ဗ်ာ။
picOriginalImg ရဲ႕ MouseMove_Event ထဲသို႔၀င္ၿပီး ေအာက္ပါ Coding ကိုထပ္ေရးယူလိုက္ပါဗ်ာ။ ဒီမွာလည္း ခက္ခဲတာ ဘာမွမပါ ပါဘူးဗ်ာ။ Coding စစခ်င္းမွာ က်ေနာ္တို႔ Crop လုပ္ခ်င္တဲ့ PictureBox ထဲမွာ Image Load ဆြဲတင္ၿပီး သားရွိ/မရွိကို အရင္စစ္ထားပါတရ္။ မရွိရင္ေတာ့ MouseMove_Event အလုပ္လုပ္မွာမဟုတ္ပါဘူး။ ရွိခဲ့ရင္ေတာ့ ဒုတိယ if()statement နဲ႔ Mouse ရဲ႕ Action ကိုဖမ္းၿပီး Left-Click ဖိၿပီး Drag(Move) လုပ္တာ ဟုတ္/မဟုတ္ ထပ္စစ္ထားပါတရ္။ ဟုတ္ခဲ့ရင္ေတာ့ ဘရ္ေလာက္ Width, ဘရ္ေလာက္ Height ေလာက္ထိ Crop လုပ္မရ္ဆုိတဲ့ မိတ္ေဆြတို႔ Drag ဆြဲသြားေသာ Width နဲ႔ Height ကိုမွတ္ပါတရ္။ ရလာတဲ့ တန္ဖိုးေတြကိုေတာ့ အေပၚမွာ global ေၾကျငာခဲ့တဲ့ cropWidth နဲ႔ cropHeight ထဲကို သြားသိမ္းထားပါတရ္။ ဒီမွာ ေနာက္ဆံုး MouseMove ရဲ႕ ဆံုးမွတ္ျဖစ္တဲ့ X,Y Coordinate ေတြထဲက စမွတ္(X,Y coordinate) (e.X - x နဲ႔ e.Y - y) ကိုျပန္ႏုတ္ထားတာကေတာ့ မိတ္ေဆြတို႔ Drag ဆြဲယူလိုက္တဲ့ Width and Height ကို အတိအက်လိုခ်င္လို႔ပါ။ နားမလည္ခဲ့ရင္ေတာ့ X,Y Coordinate မ်ဥ္းဆြဲၿပီး Trace လုပ္ၾကည့္ႏိုင္ပါတရ္။ ဒီ crop Image ရဲ႕ Widht and Height ဖမ္းႏိုင္တဲ့အဆင့္နဲ႔တင္ တကယ္ဆိုရင္ MouseMove_Event ရဲ႕ အလုပ္က ၿပီးပါတရ္။ ဒါကိုမွကြန္႔ၿပီး Selected Area ကို ထင္သာျမင္သာရွိေအာင္ Rectangle and Ellipse ပံုစံေလးဆြဲၿပီး ျပေစခ်င္လို႔သာ ေအာက္က သံုးေၾကာင္းက ထပ္ေရးရတာ ျဖစ္ပါတရ္။ ေအာက္က သံုးေၾကာင္းမပါလည္း အလုပ္ျဖစ္ပါတရ္။
Rectangle and Ellipse ဆြဲဖို႔အတြက္ DrawRectangle() နဲ႔ DrawEllipse() Method ေတြကိုသံုးထားပါတရ္။ Parameter ငါးခုပါၿပီး ပထမ parameter ကေတာ့ Graphic ကိုဆြဲခ်င္တဲ့ Pen Class ပါ။ ဒီမွာေတာ့ Pen ရဲ႕ Color ကို Assign လုပ္ေပးထားပါတရ္။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ ႏွစ္သက္သလို အျခား properties ေတြကို ထည့္သြင္းအသံုးျပဳႏုိင္ပါတရ္။ ေနာက္ x,y Paramenter ႏွစ္ခုကေတာ့ Graphic ရဲ႕ စမွတ္ Coordinate အမွတ္ျဖစ္ပါတရ္။ ေနာက္ဆံုး Parameter ႏွစ္ခုကေတာ့ ဆြဲယူမရ္႕ Graphic ရဲ႕ Width and Height ကို သတ္မွတ္ေပးလိုက္တာပါ။ ဒီမွာ က်ေနာ္ Graphic လုပ္ငန္းစဥ္ကို ႏွစ္ေၾကာင္းကိုတစ္ေၾကာင္းတည္းျဖစ္ေအာင္ ေပါင္းေရးထားတာပါ။ နားလည္ရ ခက္သြားမရ္ဆိုရင္ေတာ့ ...
Graphics gfx = picOriginalImg.CreateGraphics();
gfx.DrawRectangle(Pens.Gold, x, y, cropWidth, cropHeight);
gfx. DrawEllipse(Pens.DarkGoldenrod, x, y, cropWidth, cropHeight);
အခုလိုပံုစံ ခြဲေရးလို႔ရႏိုင္ပါတရ္။ ပထမ တစ္ေၾကာင္းက Graphic ဆြဲယူမရ္႕ Container ကိုသတ္မွတ္ေပးတာပါ။ က်ေနာ္တို႔က picOriginalImg အေပၚမွာဆြဲမွာျဖစ္လို႔ ၄င္း PictureBox ကိုညႊန္းေပးထားတာပဲျဖစ္ပါတရ္။ ဒုတိယ ႏွစ္ေၾကာင္းကေတာ့ သတ္မွတ္ထားတဲ့ Container ေပၚမွာ မိမိႏွစ္သက္ရာ Method ကိုအသံုးျပဳၿပီး Graphic တစ္ခုဆြဲယူ လိုက္တာပဲျဖစ္ပါတရ္။ နားလည္ၾကမရ္လို႔ ထင္ပါတရ္။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ ႏွစ္ေၾကာင္းတစ္ေၾကာင္းေပါင္းၿပီးျဖစ္ေစ၊ ႏွစ္ေၾကာင္းခြဲေရးၿပီးျဖစ္ေစ မိမိအားသာရာကို အသံုးျပဳႏိုင္ပါတရ္။
picOriginalImg.Refresh(); 
PictureBox ကို အၿမဲ Refresh ေပးထားတာကေတာ့ MouseMove Event အတြင္း ေရႊ႕သြားေသာ Pixel အတိုင္း ဆြဲယူသြားေသာ Graphic ေတြကို ျပန္ ျပန္ဖ်တ္ထုတ္ခ်င္လို႔ပါ။ မိတ္ေဆြကို သေဘာတရားကို နားလည္ေစခ်င္ရင္ေတာ့ ၄င္း cmd line ကို off ၿပီး run ၾကည့္ႏိုင္ပါတရ္။
ေနာက္ဆံုး Event တစ္ခုျဖစ္တဲ့ MouseUp_Event ကိုဆက္ေလ့လာၾကည့္မရ္။ ဒါေၾကာင့္ picOriginalImg ရဲ႕ MouseUp Event ထဲသို႔၀င္၍ ေအာက္ပါ Coding ေလးကို ၀င္ေရးယူလိုက္ပါဗ်ာ။ Coding စစခ်င္းမွာ crop Area သတ္မွတ္ေနတဲ့အခ်ိန္ Cross ေပးထားေသာ ကာဆာကို မူလပံုစံျဖစ္တဲ့(မွ်ားေခါင္းပံု) Default ျပန္ေပးလိုက္ပါတရ္။ if()statemet ကေတာ့ crop Area ရွိ/မရွိ စစ္ထားတာပါ။ မိတ္ေဆြတို႔ crop လုပ္မရ္႕ Area ဟာ 1 pixel ထက္နည္းေနရင္ အလုပ္လုပ္မွာ မဟုတ္ပါဘူးဗ်ာ။ ေနာက္တစ္ေၾကာင္းကေတာ့ Crop မလုပ္ရေသးတဲ့ Original Image ကို Bitmap အျဖစ္ Clone ပြားယူလိုက္တာပဲျဖစ္ပါတရ္။ ေနာက္တစ္ေၾကာင္းကေတာ့ Crop လုပ္ယူလိုက္တဲ့ Image ကို သိုေလွာင္ဖို႔အတြက္ Bitmap အသစ္တစ္ခု တည္ေဆာက္လိုက္တာပါ။ ၿပီးရင္ေတာ့ ၄င္း Bitmap ကို Container အျဖစ္ထားၿပီး Graphic ဆြဲယူပါ့မရ္လို႔ ခိုင္းပါတရ္။ SmoothingMode သံုးထားတာကေတာ့ မိတ္ေဆြတို႔ ဖန္တီးယူလိုက္တဲ့ Graphic ကို Smooth ျဖစ္ေစခ်င္လို႔ပါ။ ၿပီးရင္ က်ေနာ္တို႔က Crop Image ကို Ellipse ပံုစံ ျဖတ္ယူမွာျဖစ္လို႔ Ellipse အတြက္ Path ဆြဲႏိုင္ေအာင္ GraphicsPath Object တစ္ခုေဆာက္ပါတရ္။ ေနာက္ ၄င္း GraphicsPath ထဲကိုမွ က်ေနာ္တို႔ MouseDown and MouseMove Method တို႔နဲ႔ Crop လုပ္ယူလိုက္ေသာ Ellipse Graphic Path ကို Add ယူပါတရ္။ Graphic ကို Clear လုပ္ၿပီး အျဖဴေရာင္ ကာလာ Assign လုပ္ထားတာကေတာ့ က်ေနာ္တို႔ Crop ယူလိုက္ေသာ Image မွလြဲ၍ က်န္ Image Background ေနရာမ်ားကို အျဖဴေရာင္ ထားေစခ်င္လို႔ပဲ ျဖစ္ပါတရ္။ ေနာက္တစ္ေၾကာင္းမွာေတာ့ SetClip()Method ကိုအသံုးျပဳၿပီး က်ေနာ္တို႔ သတ္မွတ္ေပးၿပီးသားျဖစ္တဲ့ Ellipse Graphic Path ႀကီးတစ္ခုလံုးကို Graphic Object ထဲ Assign လုပ္ေပးၿပီး Graphic ဆြဲယူရန္အသင့္လို႔ ေျပာပါတရ္။ ေနာက္တစ္ေၾကာင္းကေတာ့ DrawImage() Method ကိုသံုးၿပီး အမွန္တကရ္ Crop Graphic ဆြဲယူတဲ့အဆင့္ပါ။ Parameter ငါးခု passing လုပ္ထားပါတရ္။ ပထမ parameter ကေတာ့ Soucre Image သို႔မဟုတ္ Original Image ပါ။ ေနာက္ parameter ႏွစ္ခုကေတာ့ စမွတ္(X,Y coordinate) သတ္မွတ္ေပးတာပါ။ ေနာက္ parameter ကေတာ့ Selected area ပါ။ Rectangle ကိုသံုးထားပါတရ္။ ေနာက္ဆံုး parameter ကေတာ့ Graphics ရဲ႕ Unit ကို သတ္မွတ္ေပးတာပဲ ျဖစ္ပါတရ္။ က်ေနာ္ကေတာ့ Pixel ကိုေရြးေပးထားပါတရ္။ မိတ္ေဆြတို႔အေနနဲ႔ေတာ့ လက္မ၊ မီလီမီတာ၊ point စတဲ့ ႏွစ္သက္ရာ Unit တစ္ခုခုနဲ႔ ေျပာင္းလဲအသံုးျပဳႏိုင္ပါတရ္။ အႏွစ္ခ်ဳပ္ခိုင္းသြားတဲ့ သေဘာကိုေျပာရရင္ Original ထဲက Select လုပ္ထားေသာ Area ကို Pixel Unit ကိုအသံုးျပဳၿပီး cropBmp ထဲသို႔ စမွတ္(0,0 Coordinate) မွ Graphic ဖန္တီးေပးပါလို႔ ခိုင္းလိုက္တာပါ။ ေနာက္ Crop Image ကို White Color ေပးၿပီး Background ကာလာကို Transparent ေျပာင္းယူတာပါ(Background Color နဲ႔ Transparent Color ညီမွ Background Transparent ျဖစ္မွာျဖစ္ပါတရ္)။ .Png Type နဲ႔ Save ရင္ေတာ့ Background Transparent Color ရၿပီး မည္သည့္ object နဲ႔မဆို တြဲဘက္အသံုးျပဳႏိုင္မွာ ျဖစ္ပါတရ္။ အျခား .Jpg တို႔နဲ႔ Save ရင္ေတာ့ Background Color ကို Black နဲ႔ သိမ္းေပးမွာျဖစ္ပါတရ္။ ေနာက္ဆံုးရလာတဲ့ cropBmp သို႔မဟုတ္ Crop Image ကိုေတာ့ Preview အျဖစ္ picResultImg PictureBox ေပၚသို႔ ဆြဲတင္ေပးလိုက္တာပဲ ျဖစ္ပါတရ္ဗ်ာ။ နားလည္ႏိုင္ၾကလိမ့္မရ္လို႔ ေမွ်ာ္လင့္ပါတရ္။
Coding တစ္ေၾကာင္းခ်င္းစီကိုေတာ့ အေသးစိတ္ ရွင္းျပခဲ့ပါတရ္။ ပိုၿပီး နားလည္ေစခ်င္တရ္ ဆိုရင္ေတာ့ Coding အျပည့္အစံုကို ေအာက္မွာ ေလ့လာၾကည့္ႏိုင္ပါတရ္ဗ်။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။