C# - Reduce/Compress Image Quality

Posted by ေတဇာလင္း Monday 23 January 2017 0 comments

မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမမ်ား အားလံုးပဲ မဂၤလာပါဗ်ာ။ ဒီေန႔ေတာ့ က်ေနာ္တို႔ Visual Studio C# ကို အသံုးျပဳၿပီး Image တစ္ခုရဲ႕ Size/Length ကို ဘရ္လို ေလွ်ာ့ခ်ႏိုင္မလဲ ဆိုတာေလးနဲ႔ ပါတ္သတ္ၿပီး ေလ့လာၾကည့္ၾကမွာျဖစ္ပါတရ္။ Image ရဲ႕ Quality ကို ေကာင္းေအာင္ ႀကိဳးစားေနၾကတဲ့ေခာတ္မွာ Quality ေလ်ာ့ခ်မရ္ဆိုေတာ့ ထူးထူးဆန္းဆန္းျဖစ္ေကာင္း ျဖစ္ေနပါလိမ့္မရ္။ ဒါေပမဲ့ Mega pixel ေကာင္းေကာင္းရဲ႕ Record ယူထားတဲ့ ဓါတ္ပံုတစ္ပံုဟာ အနည္းဆံုး 1MB နဲ႔ 6MB ေလာက္ထိရွိပါတရ္။ ဒါဆိုရင္ ဓါတ္ပံုေတြ အရမ္းမ်ားလာရင္ မိတ္ေဆြအတြက္ Stroage Space မွာ ျပႆနာရွိလာမွာပါ။ ဒါေၾကာင့္ ဒီ Problem ကို ေျဖရွင္းတဲ့အခါမွာ တစ္ေထာင့္တစ္ေနရာက အေထာက္အကူ ျဖစ္လိုျဖစ္ငွား ဒီေလ့က်င့္ခန္းကို ေဆြးေႏြးေပးျခင္းျဖစ္ပါတရ္။ ေျဖရွင္းၾကတဲ့ နည္းလမ္းေပါင္းစံုရွိၾကမွာပါ။ အဲ့ဒီ နည္းလမ္းေတြထဲက တစ္ခုေပါ့ဗ်ာ။ ဒီလို ေျဖရွင္းမွ ေျပလည္ႏိုင္မရ္လို႔ေတာ့ မဟုတ္ပါဘူး။ က်ေနာ့္ ေဆြးေႏြးေပးမႈမွာလည္း အားနည္းခ်က္ေတြ အမ်ားႀကီးရွိပါတရ္။ ဒါအျပင္ က်ေနာ့္ ေလ့က်င့္ခန္းေတြက စတင္ေလ့လာသူမ်ားအတြက္သာ ရည္ရြယ္လို႔ သိၿပီးသားသူေတြအတြက္ နားလည္ေပးၾကဖို႔ ႀကိဳတင္ေတာင္းပန္ထားပါရေစဗ်ာ။ ေလ့က်င့္ခန္းေတြကေတာ့ အခန္းဆက္ ပံုစံမ်ိဳးျဖစ္ေနလို႔ ေရွ႕အပိုင္းေတြမွာ သံုးခဲ့တာေလးေတြပါ ျပန္လည္အသံုးျပဳသြားမွာျဖစ္ပါတရ္။ ဒါေၾကာင့္ ေရွ႕သင္ခန္းစာရဲ႕ GUI မွာပဲ က်ေနာ္တို႔ လိုအပ္တဲ့ Tool ေလးေတြကို ထပ္ျဖည့္ၿပီး ေလ့လာၾကည့္ၾကပါ့မရ္။ ဒီေန႔ ေလ့က်င့္ခန္းအတြက္ က်ေနာ္ TrackBar (၁)ခု၊ Button (၁)ခုနဲ႔ Label (5)ခုကို အသံုးျပဳထားပါတရ္။ Tools ေတြရဲ႕ Properties ေတြကိုေတာ့ ေအာက္ပါ Table အတိုင္း ျပင္ယူလိုက္ၾကပါဗ်ာ။
PictureBox အတြင္းသို႔ Image ဆြဲတင္ျခင္းအပိုင္းနဲ႔ PictureBox အတြင္းမွ Image Information ၾကည့္တဲ့အပိုင္းကိုေတာ့ ေရွ႕ သင္ခန္းစာေတြမွာ ေလ့လာခဲ့ၿပီးျဖစ္ပါတရ္။ ဒါေၾကာင့္ coding ေတြကို က်ေနာ္ မရွင္းေတာ့ပါဘူး။ ယခု ေလ့က်င့္ခန္းမွာေတာ့ မိတ္ေဆြ ဆြဲတင္ထားတဲ့ Image ဟာ Quality ဘရ္ေလာက္ထိ ေလွ်ာ့ခ်ရင္ Image ရဲ႕ Size ဘရ္ေလာက္ထိ ေလွ်ာ့က်သြားႏိုင္လဲ ဆိုတာေလးကို ေလ့လာၾကည့္မွာပါ။ GUI ပံုစံကိုေတာ့ ေအာက္ကပံုမွာ ၾကည့္ႏိုင္ပါတရ္။
စဥ္းစားပံုကေတာ့ မိတ္ေဆြေရြးခ်ယ္လိုက္တဲ့ Image ရဲ႕ ကနဦး Quality ကို 100 လို႔ သတ္မွတ္လိုက္ပါတရ္။ ဒီ 100 Quality ကိုမွ မိမိစိတ္ႀကိဳက္ေလွ်ာ့ခ်ၿပီး Image ရဲ႕ Size/Length ကို ေလွ်ာ့ခ်ယူမွာပါ။ ဒီလို Quality ကို စိတ္ႀကိဳက္ ခ်ိန္ယူႏိုင္ဖို႔အတြက္ေတာ့ က်ေနာ္ TrackBar ကို သံုးထားတာပါ။ TrackBar ရဲ႕ BoundRate ကေတာ့ 0 to 100 ပါ။ TrackBar ရဲ႕ Rate အတိုး/အေလွ်ာ့ေပၚမူတည္ၿပီး Image ရဲ႕ Size/Length အခ်ိန္းအေျပာင္းကို ျပခ်င္တာျဖစ္တဲ့အတြက္ Calling Mehtod ကို TrackBar ရဲ႕ Scroll_Event ထဲမွာ ၀င္ေရးထားပါတရ္။ Reduce လုပ္ငန္းစဥ္ကိုေတာ့ သီးသန္႔ Method ခြဲၿပီးေရးထားပါတရ္။ Method ထဲကို Image နဲ႔ Quality ကို Parameter Passing လုပ္ထားပါတရ္။ တြက္ခ်က္ၿပီး ေနာက္ဆံုး Result အျဖစ္ Image ကို Return ျပန္ေပးမွာျဖစ္ပါတရ္။ ReduceImage ရဲ႕ Information ျပန္ၾကည့္တဲ့အပိုင္းကိုေတာ့ ေရွ႕သင္ခန္းစာက လုပ္ငန္းစဥ္အတိုင္း ျပန္သံုးထားပါတရ္။ Result ကို ပံု(၂)မွာၾကည့္ပါ။
မိတ္ေဆြတို႔ ေသခ်ာနားလည္သြားေအာင္ CompressImageQuality() Mehtod ရဲ႕ Coding ကိုေအာက္မွာ ေဖာ္ျပေပးထားပါတရ္။
ဒီမွာ အလုပ္ လုပ္သြားတာကေတာ့ Image.Save(savePath, TypeEncoder, EncodeImageQuality) Method ပါ။ ပထမ Parameter ျဖစ္တဲ့ Image ကို Save ဖို႔ File Path ကိုေတာ့ Physical Drives ကို တိုက္ရိုက္မညႊန္းေပးပဲ MemoryStream ထဲမွာ ေခတၱသိမ္းထားတဲ့ ပံုစံနဲ႔ ေရးထားပါတရ္။ ဒုတိယ Parameter ျဖစ္တဲ့ Image TypeEncoder အပိုင္းမွာေတာ့ Linq Method ကို အသံုးျပဳၿပီး Jpeg Format နဲ႔ Encode လုပ္ထားပါတရ္။ Linq မသံုးခ်င္ရင္ေတာ့ For/Foreach Loop တစ္ခုခုကိုအသံုးျပဳၿပီး ImageCodecInfo ရဲ႕ GetImageDecoders() ထဲက Jpeg Format ကို loop ပါတ္ ဆြဲထုတ္တဲ့နည္းနဲ႔ယူႏိုင္ပါတရ္ဗ်။ ဒီမွာ Jpeg Format နဲ႔ Encode လုပ္ရတာကေတာ့ Image ရဲ႕ Quality ကို အရမ္းႀကီးမဆံုးရႈံးရပဲနဲ႔ Image ရဲ႕ Size/Length ကို ေလွ်ာ့ခ်ႏိုင္လို႔ပါ။ Jpeg မဟုတ္ပဲ မိတ္ေဆြတို႔ ေရြးခ်ယ္လိုက္တဲ့ File Type အတိုင္း Endoce လုပ္ခ်င္ရင္ေတာ့ ေအာက္မွာ က်ေနာ္ ဘေလာ့ထားတဲ့ cmd line ကို သံုးႏိုင္ပါတရ္။ ဒါဆိုရင္ေတာ့ မိတ္ေဆြတို႔ Png ဆြဲတင္ရင္ Png နဲ႔ Encode လုပ္သလို Gif ဆြဲတင္ရင္ Gif နဲ႔ Encode လုပ္မွာပါ။ Jpeg Format နဲ႔ Endoce လုပ္သေလာက္ေတာ့ Image ရဲ႕ Size/Length က်သြားမွာ မဟုတ္ဘူးဆိုတာေတာ့ သတိထားရမွာပါ။ ေနာက္ဆံုး Parameter ျဖစ္တဲ့ EncodeImageQuality အပိုင္းမွာေတာ့ EncoderParameters Class ကုိသံုးထားပါတရ္။ ဒီေကာင္ရဲ႕ အဓိကအလုပ္ကေတာ့ Image အား မိမိတို႔ ေလွ်ာ့ခ်ေစခ်င္တဲ့ Quality ကို သတ္မွတ္တာပါ။ Parameter သံုးခုလံုးကို ၿခံဳငံုၿပီးေျပာရရင္ Image အား ပထမ Parameter ျဖစ္တဲ့ Path ထဲကို ဒုတိယ Parameter မွာ ေရြးခ်ယ္ထားတဲ့ Type နဲ႔ တတိယ Parameter မွာ သတ္မွတ္ေပးလိုက္တဲ့ Quality အတိုင္း Save ပါလို႔ ခိုင္းလိုက္တာပါပဲဗ်ာ။

byte[] Array ထဲ သိမ္းထားလိုက္တာကေတာ့ Image Type အေနနဲ႔ တိုက္ရိုက္ Return ျပန္လို႔မရလို႔ တဆင့္ခံအေနနဲ႔ ေခတၱသိမ္းလို္က္တာပါ။ ေနာက္ဆံုးမွာေတာ့ byte[] Array ကို MemoryStream ထဲ ျဖတ္ၿပီး က်ေနာ္တို႔ လိုခ်င္တဲ့ Image Type ေျပာင္းကာ Return ျပန္ေပးလို္က္တာပဲျဖစ္ပါတရ္ဗ်ာ။ က်ေနာ္က ကုဒ္ အလုပ္ လုပ္သြားတဲ့ သေဘာတရားကိုပဲ ရွင္းျပခဲ့တာပါ။ Encode/Decode အပိုင္းကို အေသးစိတ္ သိခ်င္ရင္ေတာ့ ထပ္ေလ့လာၾကည့္ၾကဖို႔ တိုက္တြန္းခ်င္ပါတရ္ဗ်ာ။

Reduce Method ဖန္တီးျခင္းအပိုင္းကို သိၿပီဆိုရင္ေတာ့ ၄င္း Method ကို ဘရ္လို ျပန္ေခၚသံုးမလဲဆုိတာေလးကို ေလ့လာၾကည့္ပါ့မရ္။ TrackBar ကို D_Click ေပးၿပီး Scroll_Event ထဲမွာ ၀င္ေရးလိုက္ပါဗ်ာ။
ခက္ခက္ခဲခဲ မရွိပါဘူးဗ်ာ။ Prarmeter Passing လုပ္ေပးရမဲ့ Image နဲ႔ Quality ကို Initial လုပ္ၿပီး Method ကို ေခၚလိုက္ယံုပါပဲ။ Method က Image Return ျပန္ေပးမွာျဖစ္တဲ့အတြက္ Image အေနနဲ႔ ျပန္ဖမ္းယံုပါပဲ။ ရလာတဲ့ Image ကိုေတာ့ ဒုတိယ PictureBox ျဖစ္တဲ့ picReduceImg ထဲကို Add ေပးလိုက္တာပါ။ ေလွ်ာ့က်သြားတဲ့ Image ရဲ႕ Information ထုတ္ၾကည့္တာကေတာ့ ေရွ႕သင္ခန္းစာမွာ ေလ့လာခဲ့တာနဲ႔ အတူတူပါပဲဗ်ာ။ က်ေနာ္ျပထားတဲ့ ဥပမာမွာဆုိရင္ 5.46MB ရွိတဲ့ Image တစ္ခုကို Quality ကို 56 အထိ ေလွ်ာ့ခ်လိုက္တဲ့အခါ 480KB ေလာက္ထိ ေလွ်ာ့က်သြားတာ ေတြ႔ရမွာပါ။ ပံုကို ဖြင့္ၾကည့္တဲ့အခါမွာလည္း အရမ္းႀကီး Quality က်ၿပီး ၀ါးသြားတာမ်ိဳးမရွိပါဘူးဗ်။
မိတ္ေဆြတို႔ ပိုၿပီး နားလည္သြားေအာင္ Coding အျပည့္အစံုကို ေအာက္မွာ ေလ့လာၾကည့္လိုက္ၾကပါအံုးဗ်ာ။
ကဲ... ဒီေလာက္ဆိုရင္ေတာ့ မိတ္ေဆြတို႔အေနနဲ႔ Image တစ္ခုရဲ႕ Quality ကို C# ကိုအသံုးျပဳၿပီး ေလွ်ာ့ခ်တတ္ၿပီလို႔ ထင္ပါတရ္ဗ်ာ။ က်ေနာ့္ အားနည္းခ်က္မ်ားရွိခဲ့ရင္လည္း ျပန္လည္ ေထာက္ျပေပးၾကပါဗ်ာ။ မိတ္ေဆြ၊ ညီအစ္ကို၊ ေမာင္ႏွမအားလံုး ေလ့လာျခင္းျဖင့္ ေက်နပ္ႏိုင္ၾကပါေစ။

0 Responses so far.

Post a Comment