Преобразование изображений в Windows Forms

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

Мой код:

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

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

введите описание изображения здесь

1 ответ

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

  • Выбранный формат файла возвращается 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, были сокращены до 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
Другие вопросы по тегам