2017-05-25 38 views
1

我在SkayaSharp中使用SKamait.Forms項目的SKBitmap.Resize()方法來調整顯示的圖像大小。我遇到的問題是在iOS上拍攝照片時,如果照片是以縱向拍攝的,則圖像會以右側顯示。在Android上拍照時,Android和iOS設備上的照片庫導入都會保持方向,但在iOS中拍照不會。如果我不使用SkiaSharp調整圖像大小(僅顯示圖像而不進行任何大小調整),則圖像將以正確的方向顯示。然而,這不是一個解決方案,因爲圖像需要調整大小。下面是我的代碼 -當使用SkiaSharp調整大小時iPhone的圖像方向錯誤

private byte[] GetResizedImageData(string imageName) 
    { 
     float resizeFactor = 0.5f; 
     var filePath = PathUtil.GetImagePath(imageName); 
     var ogBitmap = SKBitmap.Decode(filePath); 

     float fWidth = ogBitmap.Width * resizeFactor; 
     int width = (int) Math.Round(fWidth); 

     float fHeight = ogBitmap.Height * resizeFactor; 
     int height = (int) Math.Round(fHeight); 

     if (height >= 4096 || width >= 4096) 
     { 
      width = width * (int)resizeFactor; 
      height = height * (int)resizeFactor; 
     } 

     var scaledBitmap = ogBitmap.Resize(new SKImageInfo(width, height), SKBitmapResizeMethod.Box); 
     var image = SKImage.FromBitmap(scaledBitmap); 
     var data = image.Encode(SKEncodedImageFormat.Jpeg, 100); 

     return data.ToArray(); 
    } 

PathUtil.GetImagePath()僅僅是一個輔助以獲取被存儲的照片,其中特定於平臺的路徑。

+0

您應經常閱讀的圖像(EXIF)的iPhone肖像通常被標記爲'UIImageOrientation.Right',在Android上的原生取向事情變得非常混亂,因爲不同的製造商有時將其相機傳感器順時針或逆時針安裝90度(Samsumg和LG在90度旋轉方面聲名狼借,我甚至使用了幾個中國安卓設備,其中傳感器安裝在180度,大部分時間由於物理製造和包裝的限制,道德故事,在閱讀ap前的圖像旋轉使用任何轉換... ;-) – SushiHangover

+3

您可以通過'SKCodec.Origin'和'SKCodecOrigin'獲取Exif方向,確定您需要應用的適當轉換。 – SushiHangover

+0

所以抓住後,我似乎無法更改SKCodec.Origin,因爲它只讀,我將圖像作爲字節數組輸出到Xamarin.Forms Image.ImageSource我似乎無法處理旋轉/轉化。我想我將不得不添加特定於平臺的代碼來處理位圖方向更改。 – marcus

回答

1

SkiaSharp實際上並沒有提供一種方法來操縱和改變圖像的方向。最後,我最終改變了方向,因爲我使用平臺特定的代碼捕獲並保存了圖像。

1

對於那些有同樣問題的人,我做了以下工作,並樂意接受改進意見。

 public static SKBitmap HandleOrientation(SKBitmap bitmap, SKCodecOrigin orientation) 
    { 
     SKBitmap rotated; 
     switch (orientation) 
     { 
      case SKCodecOrigin.BottomRight: 

       using (var surface = new SKCanvas(bitmap)) 
       { 
        surface.RotateDegrees(180, bitmap.Width/2, bitmap.Height/2); 
        surface.DrawBitmap(bitmap.Copy(), 0, 0); 
       } 

       return bitmap; 

      case SKCodecOrigin.RightTop:             
       rotated = new SKBitmap(bitmap.Height, bitmap.Width); 

       using (var surface = new SKCanvas(rotated)) 
       { 
        surface.Translate(rotated.Width, 0); 
        surface.RotateDegrees(90); 
        surface.DrawBitmap(bitmap, 0, 0); 
       } 

       return rotated; 

      case SKCodecOrigin.LeftBottom: 
       rotated = new SKBitmap(bitmap.Height, bitmap.Width); 

       using (var surface = new SKCanvas(rotated)) 
       { 
        surface.Translate(0, rotated.Height); 
        surface.RotateDegrees(270); 
        surface.DrawBitmap(bitmap, 0, 0); 
       } 

       return rotated; 

      default:      
       return bitmap;    
     } 

然後使用以下來獲取原始方向。

  // TODO: Improve this.. I do not know how to "reset" 
      // the inputStream, so new it up twice. :/ 
      using (var inputStream = new SKManagedStream(imageIn)) 
      { 
       using (var codec = SKCodec.Create(inputStream)) 
       { 
        orientation = codec.Origin; 
       } 
      } 

....... 然後

SKBitmap orientedWExif = HandleOrientation(resized, orientation); 
+0

向上投票以獲取有關如何從流(或字節[])獲取源的信息:SKCodec.Create,謝謝 –