Arint System.Drawing.Graphics предполагает запись / изменение изображения, к которому он прикреплен? - PullRequest
0 голосов
/ 29 декабря 2018

При использовании графического объекта не должны ли изменения в растровом изображении (исходном изображении) быть в какой-то момент?Запустив код ниже, я получаю 5 изображений, которые все идентичны исходному.1.bmp, 2.bmp, 3.bmp, 4.bmp и 5.bmp идентичны «scaleCharacter», за исключением того, что 4 и 5 имеют более высокое сжатие (меньший размер файла)

Private Function DrawCharacterMenu() As Boolean

    Try
        'Background
        Dim rect As Rectangle = New Rectangle(100, 100, 128, 128)
        Graphics.FromImage(Render).FillRectangle(Brushes.Black, rect)

        'Scale up sprite
        Dim scaleCharacter As Bitmap = ActiveCharacter.img.Clone
        Using grDest = Graphics.FromImage(scaleCharacter)
            scaleCharacter.Save("1.bmp")
            grDest.ScaleTransform(4.0F, 4.0F)
            scaleCharacter.Save("2.bmp")
            grDest.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor
            scaleCharacter.Save("3.bmp")
            grDest.DrawImage(scaleCharacter, 0, 0)
            scaleCharacter.Save("4.bmp")
        End Using
        scaleCharacter.Save("5.bmp")

        'Draw scaled up sprite to rendering
        Graphics.FromImage(Render).DrawImage(scaleCharacter, 100, 100)

    Catch ex As Exception
        addDebugMessage("Error: Mainmenu.DrawCharacterMenu: " & ex.Message)
        Return False
    End Try

    Return True
End Function

Я бы ожидал1 должен быть таким же, как 'scaleCharacter'

2 и выше, чтобы быть в 4 раза больше (от 32x32 до 128x128)

3 и выше, чтобы иметь меньшую интерполяцию (не выглядит растянутой)

Готовый 'scaleCharacter', нарисованный на рендере, также идентичен исходному изображению ...

1 Ответ

0 голосов
/ 29 декабря 2018

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

  1. Graphics.ScaleTransform() изменяет только внутреннюю матрицу "мира", используемую при рисовании примитивов.ScaleTransform(4.0F, 4.0F) делает сетку для рисования в 4 раза шире и в 4 раза выше, , но не меняет само изображение , пока на нем что-то не будет нарисовано.Например, если бы вы теперь нарисовали прямоугольник размером 20 x 10 на своем изображении, это привело бы к прямоугольнику размером 80 x 40.

    Чтобы изменить размер фактического изображения, необходимо создать новое растровое изображение с масштабированнымразмер, затем нарисуйте старое изображение, масштабированное на него.

  2. Изменение Graphics.InterpolationMode влияет только на вновь нарисованных объектов.Опять же, это не изменит ваше изображение, пока вы не нарисуете на нем что-то.

  3. Наконец, в то время как grDest.DrawImage(scaleCharacter, 0, 0) действительно меняет ваше изображение, оно рисует то же самое изображение в верхнем левом углу (0, 0), поэтому видимых изменений нет.

Вот как вы можете заставить его работать:

МасштабированиеВаше изображение:

'Scale factor.
Dim scaleFactor As Single = 4.0F

'Create a new bitmap of the scaled size.
Using scaledBmp As New Bitmap(scaleCharacter.Width * scaleFactor, scaleCharacter.Height * scaleFactor)
    Using g As Graphics = Graphics.FromImage(scaledBmp)
        'Draw the old image, scaled, onto the new one.
        'srcRect:  The rectangle specifying which portion of the source image (scaleCharacter) to draw.
        '          We want the full image so we specify (0, 0, source width, source height).
        'destRect: The rectangle specifying where on the destination image (scaledBmp) to draw the source image.
        '          Since we want to scale it we specify the full destination image (0, 0, dest width, dest height).
        Dim srcRect As New Rectangle(0, 0, scaleCharacter.Width, scaleCharacter.Height)
        Dim destRect As New Rectangle(0, 0, scaledBmp.Width, scaledBmp.Height)
        g.DrawImage(scaleCharacter, destRect, srcRect, GraphicsUnit.Pixel)

        'Save the image.
        scaledBmp.Save("2.bmp")
    End Using
End Using

Масштабирование изображения с использованием интерполяции ближайшего соседа:

'Create a new bitmap of the scaled size.
Using scaledBmp As New Bitmap(scaleCharacter.Width * scaleFactor, scaleCharacter.Height * scaleFactor)
    Using g As Graphics = Graphics.FromImage(scaledBmp)
        'Set the interpolation mode before drawing.
        g.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor

        'Draw the old image, scaled, onto the new one.
        'srcRect:  The rectangle specifying which portion of the source image (scaleCharacter) to draw.
        '          We want the full image so we specify (0, 0, source width, source height).
        'destRect: The rectangle specifying where on the destination image (scaledBmp) to draw the source image.
        '          Since we want to scale it we specify the full destination image (0, 0, dest width, dest height).
        Dim srcRect As New Rectangle(0, 0, scaleCharacter.Width, scaleCharacter.Height)
        Dim destRect As New Rectangle(0, 0, scaledBmp.Width, scaledBmp.Height)
        g.DrawImage(scaleCharacter, destRect, srcRect, GraphicsUnit.Pixel)

        'Save the image.
        scaledBmp.Save("3.bmp")
    End Using
End Using
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...