2016-12-16 5 views
4

Ich nähe mehrere Bilder vertikal und horizontal zusammen, um ein größeres Bild (in dem die gesamte Breite und Höhe die Summe der Breiten und Höhen der einzelnen Bilder sind) unter Verwendung von Bitmap und System.Drawing.Graphics in C# zu erstellen. Die Größe der einzelnen Bilder beträgt 256 px zu 256 px.DrawImage skaliert Originalbild

Wenn ich DrawImage von System.Drawing.Graphics verwende, warum bekomme ich eine skalierte und/oder gezoomte Version des Originalbildes?


Hier ist das Original-Bild:

original image


Wenn ich das Bild programmatisch und schreiben abzurufen in Code-Datei, erhalte ich folgendes:

var result = httpClient.GetStreamAsync(/* url */); 
var bitmap = new Bitmap(await result); 
... 
using (var memory = new MemoryStream()) 
{ 
    using (var fs = new FileStream(/* path */, FileMode.OpenOrCreate, FileAccess.ReadWrite)) 
    { 
     bitmap.Save(memory, ImageFormat.Png); // I save to .png if that makes a difference 
     var bytes = memory.ToArray(); 
     await fs.WriteAsync(bytes, 0, bytes.Length); 
    } 
} 

programmatic retrieval of image in code

Ich sehe keinen Unterschied. So weit, ist es gut.


Allerdings, wenn ich Bilder versuchen, horizontal zu nähen, erhalte ich folgenden:

Hinweis: Als Referenz wird das Bild oben auf die unten weit rechts im Bild genäht ist.

horizontally stitched image

Es skaliert sieht, vergrößert und auf jeden Fall das Original oder programmatisch über Einzelbild nicht wie abgerufen.


Hier ist der Code, den ich verwende, um die Bilder zu nähen zusammen:

Hinweis: Wenn byWidthtrue, ich Stich horizontal Bilder.

private Bitmap MergeImages(IEnumerable<Bitmap> images, bool byWidth) 
{ 
    var enumerable = images as IList<Bitmap> ?? images.ToList(); 

    var width = 0; 
    var height = 0; 

    foreach (var image in enumerable) 
    { 
     if (byWidth) 
     { 
      width += image.Width; 
      height = image.Height; 
     } 
     else 
     { 
      width = image.Width; 
      height += image.Height; 
     } 
    } 

    var bitmap = new Bitmap(width, height); 
    using (var g = Graphics.FromImage(bitmap)) 
    { 
     var localWidth = 0; 
     var localHeight = 0; 

     foreach (var image in enumerable) 
     { 
      if (byWidth) 
      { 
       g.DrawImage(image, localWidth, 0); 
       localWidth += image.Width; 
      } 
      else 
      { 
       g.DrawImage(image, 0, localHeight); 
       localHeight += image.Height; 
      } 
     } 
    } 

    return bitmap; 
} 

Antwort

4

Ja, DrawImage skaliert die Bildausgabe auf der DPI-Einstellung des Bildes auf Basis gezogen werden. Ein Bitmap-Bild, das bei 72 DPI gespeichert wurde, wird so skaliert, dass es dem 96-DPI-Wert des Bildschirms entspricht, auf dem Sie es zeichnen (oder die DPI, auf die Ihr Bildschirm tatsächlich eingestellt ist). Die Idee hierbei ist, dass die Quellenauflösung (DPI) so getroffen werden sollte, dass sie mit der Zielauflösung (DPI) übereinstimmt, um die Auflösungsunabhängigkeit aufrechtzuerhalten.

Verwirrenderweise verwendet sogar die DrawImageUnscaled Methode diese DPI-basierte Skalierungslogik. Praktisch ist dies, weil die DrawImageUnscaled Methode nur ein einfacher Wrapper um eine der Überladungen von DrawImage ist. Konzeptionell scheint mir das ein Fehler zu sein.

In jedem Fall ist die Lösung einfach: Übergeben Sie die gewünschte Bildgröße explizit an den DrawImage Aufruf. Im Wesentlichen ist es zwingt Sie auf die gewünschte Größe zu skalieren:

g.DrawImage(img, 0, 0, img.Width, img.Height); 

Diese in KB317174 quasi-dokumentiert ist.