2016-01-19 1 views
2

Я пытаюсь создать изображение, накладывая один поверх другого. Код работает, но изображение, которое я накладываю, кажется немного растянутым, и я не могу понять, почему.При наложении двух изображений одинакового размера один смещен

Таким образом, код просто создает пустой красный 24x24 прямоугольник, то я наложить 24x24 PNG-файл, который выглядит следующим образом:

enter image description here

Что я ожидал это:

enter image description here

Но я фактически получаю это:

enter image description here

Using backGround As New Bitmap(24, 24, Imaging.PixelFormat.Format32bppArgb) 
     Using g = Graphics.FromImage(backGround) 
      Using brush1 As New SolidBrush(Color.Red) 
       g.FillRectangle(brush1, 0, 0, 24, 24) 
       Using topimage = Image.FromFile("C:\Scratch\ManNoRecords24.png") 
        g.DrawImage(topimage, New Point(0, 0)) 
       End Using 
      End Using 
     End Using 
     backGround.Save("C:\Scratch\Emp.png", Imaging.ImageFormat.Png) 
    End Using 

Debugger, показывающий свойства topImage:

enter image description here

+0

В отладчике проверьте размеры 't opimage'. Кто они такие? Это 24x24, как вы ожидаете? –

+0

Да, я проверил, что это действительно 24x24 –

+3

Возможно ли, что в файле png есть необычный DPI? То же самое происходит с другим верхним изображением? – Eric

ответ

4

Вы можете использовать

g.DrawImageUnscaledAndClipped(topimage, New Rectangle(0, 0, 24, 24)) 

вместо того, чтобы избежать каких-либо масштабирование исходного изображения при рисовании его. Это работает, но я на самом деле не совсем уверен, что не так с вашим решением.

С Reference Source, DrawImageUnscaledAndClipped, кажется, использует Pixel в качестве единицы по умолчанию для размера изображений и, следовательно, игнорирует настройку DPI исходного изображения:

/// <include file='doc\Graphics.uex' path='docs/doc[@for="Graphics.DrawImageUnscaledAndClipped"]/*' /> 
/// <devdoc> 
/// </devdoc> 
public void DrawImageUnscaledAndClipped(Image image, Rectangle rect) { 
    if(image == null) { 
     throw new ArgumentNullException("image"); 
    } 

    int width = Math.Min(rect.Width, image.Width); 
    int height = Math.Min(rect.Height, image.Height); 

    //We could put centering logic here too for the case when the image is smaller than the rect 
    DrawImage(image, rect, 0, 0, width, height, GraphicsUnit.Pixel); 
} 

DrawImage и DrawImageUnscaled не затем, вероятно, переранжировать изображение основанный на его внутренней настройке DPI, которую Мэтт обнаружил меньше, чем значение по умолчанию 96, что приводит к растягиванию изображения:

/// <include file='doc\Graphics.uex' path='docs/doc[@for="Graphics.DrawImageUnscaled"]/*' /> 
/// <devdoc> 
/// </devdoc> 
public void DrawImageUnscaled(Image image, Point point) { 
    DrawImage(image, point.X, point.Y); 
} 
+0

Да, мне любопытно. – Jens

+1

Похоже, что backGround имеет горизонтальное и вертикальное разрешение '96', тогда как PNG на диске по какой-то причине имеет' 71.9582', поэтому это будет учитывать эту разницу –

+2

@MattWilko Хорошо, это сложно найти. Я искал источник ссылки для рисования изображения. При использовании 'DrawImageUnscaledAndClipped' вызов в источнике .NET специально устанавливает' GraphicsUnit' в 'Pixel', в то время как другие методы этого не делают. Таким образом, параметр DPI игнорируется, в то время как другие методы, вероятно, используют «Point» и, следовательно, учитывают изображение DPI. – Jens