在實際項目中,可能需要使用者從相簿中選擇圖片然後進行相應的處理。但是不知道大家有沒有發現這樣一種情況,就是手機裡看是豎著的,但是上傳到微博或者哪裡的時候確實橫著的。一種情況是你拿手機豎著拍照得話,照片就是橫著的,雖然在手機裡看是豎著的。(可能有點抽象,遇到此情況的同學應該深有感觸)
那麼我們在用戶端中應該如何處理這種情況呢?一種想法是擷取圖片的角度,如果是90°,就把照片翻轉過來,再進行相應的操作。那這樣就涉及到2個問題
1. 如何擷取相簿中照片的角度
2. 如何翻轉已有的照片(流、或者Bitmap或者WriteableBitmap)
查看了系統的API,並沒有對相片的角度提供支援,但是我們可以使用ExifLib開源庫去做。
下述的方法就是擷取選取圖片的角度的
/// <summary>/// get angle of photo/// </summary>/// <param name="stream">photo stream</param>/// <param name="filename">photo name</param>/// <returns>angle of the photo</returns>public static int GetAngle(Stream stream, string filename){ ExifLib.ExifOrientation _orientation; int _angle = 0; stream.Position = 0; JpegInfo info = ExifReader.ReadJpeg(stream, filename); if (info!=null) { _orientation = info.Orientation; switch (info.Orientation) { case ExifOrientation.TopLeft: case ExifOrientation.Undefined: _angle = 0; break; case ExifOrientation.TopRight: _angle = 90; break; case ExifOrientation.BottomRight: _angle = 180; break; case ExifOrientation.BottomLeft: _angle = 270; break; } } return _angle;}
擷取到角度後,如果角度是90°,即是反的,我們需要將其糾正過來,可以使用如下的方法:
private Stream RotateStream(Stream stream, int angle){ stream.Position = 0; if (angle % 90 != 0 || angle < 0) throw new ArgumentException(); if (angle % 360 == 0) return stream; BitmapImage bitmap = new BitmapImage(); bitmap.SetSource(stream); WriteableBitmap wbSource = new WriteableBitmap(bitmap); WriteableBitmap wbTarget = null; if (angle % 180 == 0) { wbTarget = new WriteableBitmap(wbSource.PixelWidth, wbSource.PixelHeight); } else { wbTarget = new WriteableBitmap(wbSource.PixelHeight, wbSource.PixelWidth); } for (int x = 0; x < wbSource.PixelWidth; x++) { for (int y = 0; y < wbSource.PixelHeight; y++) { switch (angle % 360) { case 90: wbTarget.Pixels[(wbSource.PixelHeight - y - 1) + x * wbTarget.PixelWidth] = wbSource.Pixels[x + y * wbSource.PixelWidth]; break; case 180: wbTarget.Pixels[(wbSource.PixelWidth - x - 1) + (wbSource.PixelHeight - y - 1) * wbSource.PixelWidth] = wbSource.Pixels[x + y * wbSource.PixelWidth]; break; case 270: wbTarget.Pixels[y + (wbSource.PixelWidth - x - 1) * wbTarget.PixelWidth] = wbSource.Pixels[x + y * wbSource.PixelWidth]; break; } } } MemoryStream targetStream = new MemoryStream(); wbTarget.SaveJpeg(targetStream, wbTarget.PixelWidth, wbTarget.PixelHeight, 0, 100); return targetStream;}
Demo原始碼下載
原文Handling picture orientation in CameraCaptureTask in Windows Phone 7