天天看點

計算照片的面積(UWP篇)

今天先說UWP應用程式上計算照片面積的方法,改天有空,再說說WPF篇。

其實計算照片面積的原理真TMD簡單,隻要你有本事讀到照片的像素高度和寬度,以及水準/垂直方向上的分辨率(DPI)就可以了。計算方法也很容易,把像素值除以DPI,得到的是照片的寬度或高度,機關是英寸。

通常咱們計算面積是按平方米來算(不信你問問數位攝影店的夥計們),也可以按平方厘米來算。沒關系,隻要算出平方厘米,你就知道怎麼轉為平方米了。英寸和厘米的換算是:

1 inch = 2.54 cm

好,說服做完了,接下來就是開工。

首先,定義一個封裝照片資訊的類,UI和代碼分離嘛,最好這樣做,把要用的資料都進行封裝,這樣程式看起來也高大上,至少裝逼是沒問題的。

這個類的代碼有點長,不要緊,都是一堆屬性,重點的是那個異步方法,從照片檔案進行解碼,然後讀出圖檔大小、分辨率等資訊。

老周相信你沒有忘記BitmapDecoder這個東東,如果你忘了,請寫一份3萬字的檢讨書,并送出到應用商店。解碼後,從DpiX和DpiY兩個屬性就能讀到分辨率;從PixelWidth和PixelHeight兩個屬性可以得到用像素表示的寬度和高度。

好,需要的資料都齊全了,然後計算圖檔的寬高的英寸表示值。

最後,就可以計算單張照片的面積了,我這裡用的機關是平方厘米。

OK,這個封裝的玩意兒算完成了,下面弄UI部分。大概的XAML如下,我就不解釋了,看不懂的話,可以打電話問問憨豆先生。

ListView用來顯示每張照片的資訊,最後的TextBlock用來顯示所有照片的總面積。

然後,處理按鈕事件。

photolist是個變量,類型為ObservableCollection<PhotoInfo>,ObservableCollection集合是個好東西,它可以自動更新綁定的集合控件的UI項。

由于在讀取檔案和解碼圖檔時用到了異步等待,是以剛才在PhotoInfo類的定義時公開了一個ProcessFileAsync方法,這樣確定調用這個類的代碼也能繼續異步等待,就是等到所有資料都讀完了,都計算完了再繼續,不然最後計算總面積的時候,因為資料沒有準備好,會得到總面積為0的靈異結果。是以,做人别太急,要學會異步等待,這樣你才能看看沿途美麗如畫的風景。

是以,在向集合Add項前,要等待資料初始化完成,這個等待是異步的,不會阻止UI線程。

最後計算總面積的時候,就好辦了,直接調用集合的Sum擴充方法即可,你要是嫌代碼太短了,也可以用LinQ來計算,反正一樣的。注意,在Sum裡面的Lambda表達式體中,要判斷一下,每一個PhotoInfo執行個體的Area屬性是否有效,方法是用double.IsInfinity方法,如果double值為正無窮大或負無窮大,就傳回true,這時候應把傳回的double值調整為0,不然的話,任何數跟無窮大的數相加後的結果,永遠都是無窮大,這樣的值沒有實際價值。

為什麼要這樣驗證呢,因為個别照片檔案可能由于人品問題,讀不出正确的分辨率,這樣最後的計算結果就會有問題。

現在,運作示例,然後選擇一堆照片,就能計算它們的面積了,有圖有真相。

計算照片的面積(UWP篇)

好了,本文就寫到這裡了,改天老周再補上WPF篇。

示例源代碼下載下傳位址

繼續閱讀