Преобразование изображений в 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
Отметить:
Поскольку вы используете метод, который возвращает
Bitmap
объект, и этот объект затем назначаетсяPictureBox.Image
свойство, вам нужно избавиться от предыдущего изображения, если таковые имеются, перед назначением нового. В противном случае этот потерянный объект будет зависеть от того, что ему нужно, и это будет мешать вашему приложению.Фильтры, в
SaveFileDialog
, были сокращены доImageFormats
которые фактически поддерживаются GDI+ при создании нового растрового изображения.Icon
,WMF
,EMF
а такжеExif
не поддерживаются и полученное изображение будетPNG
формат файла, формат GDI+ по умолчанию.
Первые три могут быть созданы с помощью других средств, но это широкий вопрос и не может быть решен здесь.Несколько методов возвращают 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