2017-05-25 10 views
1

Ich verwende die SKBitmap.Resize() -Methode in SkiaSharp in einem Xamarin.Forms-Projekt, um Bilder für die Anzeige zu skalieren. Das Problem, auf das ich stoße ist, wenn ich ein Foto auf iOS mache, wenn ein Foto im Hochformat gemacht wird, wird das Bild mit der rechten Seite nach oben angezeigt. Wenn Sie ein Foto auf Android-Geräten aufnehmen, ist das Importieren aus der Fotogalerie sowohl auf einem Android- als auch auf einem iOS-Gerät die Orientierung, ein Fotografieren in iOS jedoch nicht. Wenn ich das Bild nicht mit SkiaSharp skaliere (zeige einfach das Bild ohne Größenänderung an), wird das Bild mit der richtigen Ausrichtung angezeigt. Dies ist jedoch keine Lösung, da die Bilder in der Größe geändert werden müssen. Unten ist mein Code -iPhone Bildausrichtung falsch beim Skalieren mit SkiaSharp

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() ist nur ein Helfer zu bekommen sind plattformspezifische Pfade, wo die Fotos gespeichert werden.

+0

Sie sollten die native Orientierung auf dem Bild (EXIF) als iPhones Porträts sind in der Regel als 'UIImageOrientation.Right' markiert, auf Android immer lesen Die Dinge werden wirklich unordentlich, da verschiedene Hersteller ihre Kamerasensoren manchmal um 90 Grad im oder gegen den Uhrzeigersinn montieren (Samsumg und LG sind für 90 Umdrehungen berüchtigt). Ich habe sogar ein paar chinesische Android-Geräte verwendet, bei denen die Sensoren 180 Grad installiert sind aufgrund der physischen Herstellung und Verpackung Einschränkungen, Moral der Geschichte, lesen Sie die Bildrotation vor ap irgendwelche Transformationen durchführen ... ;-) – SushiHangover

+3

Sie können die Exif-Orientierung über 'SKCodec.Origin' erhalten und aus der' SKCodecOrigin' die passende Transformation bestimmen, die Sie anwenden müssen. – SushiHangover

+0

Also nachdem ich das gefunden habe, kann ich SKCodec.Origin nicht ändern, da es nur gelesen wird und ich gebe das Bild als Bytearray an Xamarin.Forms Image.ImageSource aus, wo ich nicht mit der Rotation umgehen kann/Transformation entweder. Ich denke, ich muss plattformspezifischen Code hinzufügen, um die Bitmap-Ausrichtung zu ändern. – marcus

Antwort

1

SkiaSharp hat mir eigentlich keine Methode zur Verfügung gestellt, um die Ausrichtung des Bildes zu manipulieren und zu ändern. Am Ende änderte ich die Ausrichtung, als ich das Bild mit plattformspezifischem Code erfasste und speicherte.

1

Für diejenigen mit dem gleichen Problem habe ich Folgendes getan und würde gerne eine Eingabe über Verbesserungen akzeptieren.

 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;    
     } 

Und dann verwenden Sie die folgenden, um die ursprüngliche Ausrichtung zu erhalten.

  // 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; 
       } 
      } 

....... Dann

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

upvoted für die Informationen, wie Sie den Ursprung aus dem Stream (oder Byte []) erhalten: SKCodec.Create, danke –

Verwandte Themen