Я пытаюсь позволить пользователю выбрать файл изображения, затем изменить размер изображения до пары разных размеров, если необходимо, а затем сохранить измененные изображения в байтовые массивы, которые будут сохранены в базе данных. Я продолжаю получать ошибки при преобразовании изображения в байтовый массив (но только если изображение было изменено). Надеюсь, кто-нибудь скажет мне, что я делаю не так.
К вашему сведению, я не профессиональный программист, и обычно меня критикуют, когда я публикую свой код. Я определенно открыт для любых отзывов или предложений, которые могут у вас возникнуть, поэтому, пожалуйста, будьте любезны .. lol
Я обычно получаю эту ошибку в функции SaveImage () в строке Image.Save (mStream, TheImage.RawFormat) System.ArgumentNullException: 'Значение не может быть нулевым. Имя параметра: encoder '
Иногда я получаю ошибку фреймворка и не могу точно сказать, где происходит ошибка.
РЕДАКТИРОВАТЬ: я закончил расширение класса Image, который, кажется, работает довольно хорошо, так далеко.
Imports System.Drawing.Imaging
Imports System.IO
Module Extentions
<Runtime.CompilerServices.Extension()>
Public Function GetBytes(ByRef bc As Image, Optional Format As ImageFormat = Nothing) As Byte()
'Converts Image to Byte Array
If Format Is Nothing Then Format = ImageFormat.Jpeg
Using mStream As New MemoryStream()
bc.Save(mStream, Format)
Return mStream.ToArray()
End Using
End Function
<Runtime.CompilerServices.Extension()>
Public Function ReSize(ByRef bc As Image, MaxWidth As Integer, MaxHeight As Integer) As Image
'Resize image to fit within MaxWidth & MaxHeight while keeping aspect ratio
If MaxWidth < bc.Width Or MaxHeight < bc.Height Then
Dim Scale As Double = Math.Min(MaxWidth / bc.Width, MaxHeight / bc.Height)
Dim NewWidth As Integer = CInt(Math.Round(bc.Width * Scale))
Dim NewHeight As Integer = CInt(Math.Round(bc.Height * Scale))
Return New Bitmap(bc, New Size(NewWidth, NewHeight))
Else
Return bc
End If
End Function
End Module
Теперь мой код в той форме, над которой я работал, намного проще ..
Private Sub SelectImage_Click(sender As Object, e As EventArgs) Handles SelectImage.Click
Dim Popup As New OpenFileDialog
With Popup
.Filter = "Images|*.gif;*.png;*.jpg;*.bmp"
.Title = "Select Image"
.FileName = ""
.FilterIndex = 1
.Multiselect = False
.RestoreDirectory = True
End With
If Popup.ShowDialog = vbOK Then
'Load Image from disk
OriginalImage = Image.FromFile(Popup.FileName)
'Resize and display image on form
Picture.Image = OriginalImage.ReSize(200, 150)
'Save Large Image
FullImage = OriginalImage.ReSize(400, 300).GetBytes
'Save Small Image
SmallImage = OriginalImage.ReSize(100, 75).GetBytes
ImageSelected = True
End If
End Sub
Вот мой оригинальный код ...
Private OriginalImage As Image
Private FullImage As Byte()
Private SmallImage As Byte()
Private ImageSelected As Boolean
Private Sub SelectImage_Click(sender As Object, e As EventArgs) Handles SelectImage.Click
Dim Popup As New OpenFileDialog
With Popup
.Filter = "Images|*.gif;*.png;*.jpg;*.bmp"
.Title = "Select Image"
.FileName = ""
.FilterIndex = 1
.Multiselect = False
.RestoreDirectory = True
End With
If Popup.ShowDialog = vbOK Then
'Load Image from disk
OriginalImage = Image.FromFile(Popup.FileName)
'Resize and display image on form
Picture.Image = ResizeImage(OriginalImage, 200, 150)
'Save Large Image
Dim ResizedImage As Image = ResizeImage(OriginalImage, 400, 300)
FullImage = SaveImage(ResizedImage)
'Save Small Image
ResizedImage = ResizeImage(OriginalImage, 100, 75)
SmallImage = SaveImage(ResizedImage)
ImageSelected = True
End If
End Sub
Private Function ResizeImage(ByRef InputImage As Image, MaxWidth As Integer, MaxHeight As Integer) As Image
'ReSize the Image if needed to save space in the database
If MaxWidth < InputImage.Width Or MaxHeight < InputImage.Height Then
'ReSize Image
Dim Scale As Double = Math.Min(MaxWidth / InputImage.Width, MaxHeight / InputImage.Height)
Return New Bitmap(InputImage, New Size(Math.Round(InputImage.Width * Scale), Math.Round(InputImage.Height * Scale)))
Else
'Image size was OK
Return InputImage
End If
End Function
Private Function GetImage(ImageData As Byte()) As Image
'Converts Byte Array to Image
Using mStream As New MemoryStream(ImageData)
Return Image.FromStream(mStream)
End Using
End Function
Private Function SaveImage(TheImage As Image) As Byte()
'Converts Image to Byte Array
Using mStream As New MemoryStream()
TheImage.Save(mStream, TheImage.RawFormat)
Return mStream.ToArray()
End Using
End Function
'These are functions I was playing around with because I was getting
'System.ArgumentNullException: 'Value cannot be null. Parameter name: encoder'
'in the SaveImage() function on TheImage.Save(mStream, TheImage.RawFormat)
'and I wasn't using the encoder parameter. I couldn't get these to help me though.
Private Function SaveImage2(TheImage As Image) As Byte()
'Converts Image to Byte Array
Dim CodecInfo As Imaging.ImageCodecInfo = GetEncoderInfo("image/jpeg")
Dim Parameters As New Imaging.EncoderParameters(1)
Parameters.Param(0) = New Imaging.EncoderParameter(Imaging.Encoder.Quality, 75L)
Using mStream As New MemoryStream()
TheImage.Save(mStream, CodecInfo, Parameters)
Return mStream.ToArray()
End Using
End Function
Private Function GetEncoderInfo(MimeType As String) As Imaging.ImageCodecInfo
Dim encoders As Imaging.ImageCodecInfo()
encoders = Imaging.ImageCodecInfo.GetImageEncoders()
For j As Integer = 0 To encoders.Length - 1
If encoders(j).MimeType = MimeType Then Return encoders(j)
Next
Return Nothing
End Function