Преобразование изображений в Windows Forms - PullRequest
0 голосов
/ 24 ноября 2018

Я надеюсь, что получу это в правильном месте, супер новый здесь.Я работаю над преобразованием изображений в формах Windows.

Мой код:

Imports System.Drawing
Imports System.Drawing.Imaging

Public Class ImageConversion
     Private currentFile As String
     Private image As Image

      Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
        With OpenFile 
            .Title = "Open Image File" 
            .Filter = "Bitmap Files|*.bmp" + 
                "|Enhanced Windows MetaFile|*.emf" + 
                "|Exchangeable Image File|*.exif" + 
                "|Gif Files|*.gif" + 
                "|Icons|*.ico" + 
                "|JPEG Files|*.jpg" + 
                "|PNG Files|*.png" + 
                "|TIFF Files|*.tif" + 
                "|Windows MetaFile|*.wmf"
            .DefaultExt = "jpg" 
            .FilterIndex = 6 
            .FileName = "" 
        End With
        OpenFile.ShowDialog() 
        If OpenFile.FileName = "" Then 
            Return
        End If
        currentFile = OpenFile.FileName.ToString() 
        image = Image.FromFile(OpenFile.FileName) .
        PictureBox1.Image = image
        Me.Text = "Image Conversion -" & OpenFile.SafeFileName.ToString() 
    End Sub

    Private Sub BitmapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BitmapToolStripMenuItem.Click
        Dim newName As String = System.IO.Path.GetFileNameWithoutExtension(currentFile)
        newName = newName + ".bmp"
        If SaveFile.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                Image.Save(SaveFile.FileName, ImageFormat.Bmp)
            Catch ex As Exception
                MessageBox.Show("Failed to save image to bitmap.", "Error" & ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End Try
            MessageBox.Show("Image File Saved To" + SaveFile.FileName.ToString(), "Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub
End Class

Это затем повторяется для каждого дополнительного типа файла.Всякий раз, когда я собираюсь конвертировать, мой тип файла не меняется на желаемую конверсию, и опция сохранения не дает мне выбора, и она фактически не сохраняет его как что-либо, кроме типа файла: Файл.
Прикрепленный фрагменто том, что происходит, когда появляется всплывающее окно.
Я чувствую, что здесь что-то простое, что мне не хватает.

enter image description here

1 Ответ

0 голосов
/ 25 ноября 2018

Я изменил ваш исходный класс, добавив некоторые недостающие функции:

  • Выбранный формат файла, возвращаемый SaveFileDialog()
  • Выбором фильтров в SaveFileDialog() сокращено до форматов, которые Image.Save () фактически поддерживает
  • IDisposable, используется для удаления растрового изображения, загруженного в данный момент
  • Некоторые другиеподробности вы можете найти в примечаниях и в коде класса

Теперь это автономный класс, который можно использовать в других контекстах (нет ссылок на конкретные элементы управления или методы:

Пример использования :

Инициализация класса ImageConversion (в конструкторе формы или там, где вы считаете нужным):

Public Partial Class Form1
    Public imgConversion As ImageConversion = New ImageConversion()
    '(...)

End Class

Ваши обработчики могут быть изменены следующим образом:

Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click

    If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
    Dim NewBitmapFile = imgConversion.OpenFile()
    If NewBitmapFile.OpenedBitmap IsNot Nothing Then
        PictureBox1.Image = NewBitmapFile.OpenedBitmap
        Me.Text = NewBitmapFile.FileName
    End If
End Sub

Private Sub BitmapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BitmapToolStripMenuItem.Click
    Dim SavedFile = imgConversion.SaveFileFormat()
    If SavedFile.ErrorMessage <> String.Empty Then
        MessageBox.Show("Failed to save image to Bitmap.", "Error" & SavedFile.ErrorMessage, MessageBoxButtons.OK, MessageBoxIcon.Error)
    ElseIf SavedFile.FileName <> String.Empty Then
        MessageBox.Show("Image File saved to: " + SavedFile.FileName, "Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End If
End Sub

Удалять класс ImageConversion при закрытии формы, это освободит последний использованный объект Image:

Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    imgConversion.Dispose()
End Sub

К сведению :

  1. Так как выСпойте метод, который возвращает объект Bitmap, и этот объект затем присваивается свойству PictureBox.Image, вам необходимо избавиться от предыдущего изображения, если оно есть, перед назначением нового.В противном случае этот потерянный объект будет задерживаться на большее, чем хотелось бы, и это будет препятствовать вашему приложению.

  2. Фильтры в SaveFileDialog имеютbeed уменьшен до ImageFormats, которые фактически поддерживаются GDI + при создании нового растрового изображения.
    Icon, WMF, EMF и Exif не поддерживаются, и в результате получается изображение PNGформат файла, формат GDI + по умолчанию.
    Первые три могут быть созданы с помощью других средств, но это широкий вопрос и не может быть решен здесь.

  3. Несколько методов возвращают ValueTuple в форме ValueTuple(Of T1, T2).
    Я не уверен, что ваша версия VB.Net поддерживает этот тип и форму возврата.
    Если нет, методможет быть изменен, чтобы возвращать ByRef результаты или специализированный публичный объект (подкласс ImageConversion), который содержит необходимую информацию (вероятно, предпочтительнее).

    Public Function OpenFile() As (OpenedBitmap As Image, FileName As String)
    '(...)
    Dim result = OpenFile()
    Dim img As Bitmap = result.OpenedBitmap 
    Dim fName As String = result.FileName
    

Класс ImageConversion:

Imports System.Drawing.Imaging
Imports System.Globalization
Imports System.IO

Public Class ImageConversion
    Implements IDisposable

    Private IsDisposed As Boolean = False
    Private CurrentFile As String
    Private CurrentBitmap As Image

    Private Enum FilterType
        OpenFile
        SaveFile
    End Enum

    Public Function OpenFile() As (OpenedBitmap As Image, FileName As String)
        Using OFD As OpenFileDialog = New OpenFileDialog()
            With OFD
                .CheckFileExists = True
                .CheckPathExists = True
                .RestoreDirectory = True
                .Title = "Open Image File"
                .Filter = GetFileFilters(FilterType.OpenFile)
                .FilterIndex = 4
                .FileName = ""
            End With
            If OFD.ShowDialog() = DialogResult.Cancel Then Return Nothing

            CurrentFile = OFD.FileName
            If CurrentBitmap IsNot Nothing Then CurrentBitmap.Dispose()
            CurrentBitmap = CType(Image.FromFile(CurrentFile).Clone(), Bitmap)
        End Using
        Return (CurrentBitmap, CurrentFile)
    End Function

    Public Function SaveFileFormat() As (FileName As String, ErrorMessage As String)
        Dim NewFileName As String = Path.GetFileNameWithoutExtension(CurrentFile)
        Dim ErrorMessage As String = String.Empty
        Using SFD As SaveFileDialog = New SaveFileDialog()
            With SFD
                .AddExtension = True
                .ValidateNames = True
                .CheckPathExists = True
                .RestoreDirectory = True
                .Title = "Save Image File"
                .Filter = GetFileFilters(FilterType.SaveFile)
                .FileName = NewFileName
            End With

            If SFD.ShowDialog() = DialogResult.Cancel Then Return (String.Empty, String.Empty)
            Try
                NewFileName = SFD.FileName
                Dim imgFormat As ImageFormat = GetImageFormat(NewFileName)
                CurrentBitmap.Save(NewFileName, imgFormat)
            Catch ex As IOException
                NewFileName = String.Empty
            End Try
        End Using
        Return (NewFileName, ErrorMessage)
    End Function

    Private Function GetImageFormat(FileName As String) As ImageFormat
        Dim fileType As String = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Path.GetExtension(FileName).Remove(0, 1).ToLower())
        If fileType = "Tif" Then fileType = "Tiff"
        If fileType = "Jpg" Then fileType = "Jpeg"
        Dim imgFormat As ImageFormat = New ImageFormat(New Guid())
        Return DirectCast(imgFormat.GetType().GetProperty(fileType).GetValue(imgFormat), ImageFormat)

    End Function

    Private Function GetFileFilters(Filter As FilterType) As String
        Dim Filters As String() = {
            "BMP Files|*.bmp", "|GIF Files|*.gif", "|JPEG Files|*.jpg",
            "|PNG Files|*.png", "|TIFF Files|*.tif", "|Enhanced Windows MetaFile|*.emf",
            "|Exchangeable Image File|*.exif", "|Icons|*.ico", "|Windows MetaFile|*.wmf"
        }

        Select Case Filter
            Case FilterType.OpenFile
                Return String.Join("", Filters)
            Case FilterType.SaveFile
                Return String.Join("", Filters.Take(5))
            Case Else
                Return String.Empty
        End Select
    End Function

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    Protected Overridable Sub Dispose(disposing As Boolean)
        If IsDisposed Then Return
        If disposing Then
            If CurrentBitmap IsNot Nothing Then
                CurrentBitmap.Dispose()
            End If
        End If
        IsDisposed = True
    End Sub
End Class
...