【发布时间】:2020-06-27 01:04:53
【问题描述】:
我试图让用户选择一个图像文件,然后根据需要将图像大小调整为几个不同的大小,然后将调整大小的图像保存到将保存到数据库中的字节数组中。将图像转换为字节数组时(但仅在调整图像大小时),我不断收到错误。希望有人能告诉我我做错了什么。
仅供参考,我不是专业的程序员,当我发布我的代码时通常会受到批评。我绝对愿意接受您可能有的任何反馈或建议,所以请善待..lol
我通常在 Image.Save(mStream, TheImage.RawFormat) 行的 SaveImage() 函数中收到此错误 System.ArgumentNullException: '值不能为空。参数名称:编码器'
有时我会遇到框架错误,并且无法确定错误发生在哪里。
编辑:我最终扩展了 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
【问题讨论】:
-
使用ImageResizer库
-
TheImage.Save(mStream, ImageFormat.Png). -
更具体地说,当您在内存中生成新的位图时,RawFormat 设置为
ImageFormat.MemoryBmp。您无法使用该格式保存图像(它不是 real 格式)。顺便说一句,据我所知,您应该设置Option Strict On并解决问题,然后才能获得与预期值不完全匹配的扭曲图像或图像尺寸。 -
谢谢!我知道是这样的。我只是不知道如何使用 ImageFormat.Png 设置格式。我打开了 option strict ,看看你对双精度/整数转换的意思,我也会解决这个问题。如果你想发表你的评论作为答案,我会接受。
标签: vb.net winforms bitmap encoder .net-4.7.2