2017-05-25 12 views
1

SkamSharpのSKBitmap.Resize()メソッドをXamarin.Formsプロジェクトで使用して、表示する画像のサイズを変更しています。私が遭遇している問題は、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

あなたはいつものiPhoneの肖像画は、通常はAndroidでは、UIImageOrientation.Right' 'としてタグ付けされているとして、画像(EXIF)上のネイティブオリエンテーションをお読みくださいカメラのセンサーを時計回りまたは反時計回りに90度回転させることがあるため、物事は本当に乱雑になります(SamsumgとLGは90回転で有名ですが、センサは180度取り付けられています)。物理的な製造と包装の制約、物語の道徳のために、イメージの回転を読み取る前に、任意の変換を行う... ;-) – SushiHangover

+3

Exifの向きは 'SKCodec.Origin'で取得でき、' SKCodecOrigin'から適用する必要がある適切な変換を決定できます。 – 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

upvotedストリーム(またはバイト[])から原点を取得する方法に関する情報:SKCodec.Create、ありがとう –

関連する問題