Resize Image from Picture box to predefined size (1080p)
As an update to a program I had made awhile back, I am trying to auto-resize the image to meet the requirements of my application without having to manually do it elsewhere. I already can adjust the quality/compression for disk storage, but I want to resize the image so I can save the quality of the image.
So how do I resize an image to 1920*1080. (I want to check the image first to make sure that the image is in fact larger then 1080p before I resize it.)
I'd really like the solution to work in a DLL project so that I can move my application from the Windows Forms to the WPF UI.
Re: Resize Image from Picture box to predefined size (1080p)
There are several ways to resize an image. Maybe the simplest is like this:
Code:
myImage = New Bitmap(myImage, width, height)
I'm not sure what you mean by "save the quality of the image" because shrinking an image inevitably involves some loss of information. But I guess you want to maximize the quality of the resized image. In that case, I suggest you use this slightly more complicated method of resizing:
vb Code:
Private Function ResizeImage(sourceImage As Image, newWidth As Integer, newHeight As Integer) As Bitmap
Dim bmp As New Bitmap(newWidth, newHeight)
Using g As Graphics = Graphics.FromImage(bmp)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(sourceImage, 0, 0, newWidth, newHeight)
End Using
Return bmp
End Function
The high quality interpolation mode is slower than default resizing (about 2.5x) but it produces visibly better results.
I think it must be possible to use a dll built in WinForms in a WPF project. You can even intersperse Windows Forms code with WPF code if you add the required references such as System.Drawing and specify the namespaces of Points, Colors etc. to avoid ambiguity; but I doubt if the experts would recommend it.
BB
EDIT: by the way, Usta, welcome to VB Forums:wave:
Re: Resize Image from Picture box to predefined size (1080p)
Quote:
I'm not sure what you mean by "save the quality of the image" because shrinking an image inevitably involves some loss of information. But I guess you want to maximize the quality of the resized image. In that case, I suggest you use this slightly more complicated method of resizing:
Here is what I meant by quality. First is uncompressed, second is compressed. Not all compression will look as bad as this. But image quality is visibly lost on any huge quality change. http://www.ams.org/featurecolumn/ima...desertwall.jpg http://www.ams.org/featurecolumn/ima...sertwall.5.jpg
Thanks for your help!
Quote:
EDIT: by the way, Usta, welcome to VB Forums
and thanks!
Re: Resize Image from Picture box to predefined size (1080p)
It looks like the second image has been saved with a very high level of jpeg compression. That is not at all the same as resizing the image. It affects the size of the file, but not of the image. How are you saving the image that way?
BB
Re: Resize Image from Picture box to predefined size (1080p)
Quote:
It looks like the second image has been saved with a very high level of jpeg compression. That is not at all the same as resizing the image. It affects the size of the file, but not of the image. How are you saving the image that way?
Yeah, that is what I meant by changing the quality... (Those images were actually just from a Google search to show you the diff.)
Basically I want to resize it so that I can avoid using compression as much as possible.
Here is the code that I found for resizing it, and I have another function elsewhere to auto-resize down to 245 KB or less
Code:
Public Shared Sub SaveJpeg(ByVal path As String, ByVal img As Image, ByVal quality As Long)
If ((quality < 0) OrElse (quality > 100)) Then
Throw New ArgumentOutOfRangeException("quality must be between 0 and 100.")
End If
' Encoder parameter for image quality
Dim qualityParam As New EncoderParameter(Encoder.Quality, quality)
' Jpeg image codec
Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")
Dim encoderParams As New EncoderParameters(1)
encoderParams.Param(0) = qualityParam
img.Save(path, jpegCodec, encoderParams)
End Sub
' Returns the image codec with the given mime type
Private Shared Function GetEncoderInfo(ByVal mimeType As String) As ImageCodecInfo
' Get image codecs for all image formats
Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
' Find the correct image codec
For i As Integer = 0 To codecs.Length - 1
If (codecs(i).MimeType = mimeType) Then
Return codecs(i)
End If
Next i
Return Nothing
End Function
Looks like that code you posted should work okay....
For some reason the second example wasn't working right, but the first one was perfect!
Re: Resize Image from Picture box to predefined size (1080p)
That code looks familiar;). Do you mean you want a JPEG quality of 100 all the time? That might be appropriate for images meant for high quality photo work, but usually you would save in a lossless file format such as PNG rather than JPEG. Most programs which save JPEG images allow the user to set the quality before saving. For general photo viewing, a quality of about 60-70 is usually considered good enough. If the file size is your priority, maybe you should settle on 70 as "best possible".
It's hard to estimate how big a JPEG image will be when saved because it depends on among other things the colours in the image. I wonder how your resizing function for 245 KB goes about it? I would do a test save of the image to a MemoryStream at the required quality; then if the length of the stream turns out to be above the size limit, reduce the pixel size of the image accordingly before saving definitively. That's not to say there couldn't be a better way.
My ResizeImage function works fine for me. Did you call it as intended, like this?
Code:
Dim newImage As Image = ResizeImage(sourceImage, width, height)
BB
Re: Resize Image from Picture box to predefined size (1080p)
Code:
My ResizeImage function works fine for me. Did you call it as intended, like this?
I think it mighta been a little diff. ^_^
Quote:
That code looks familiar. Do you mean you want a JPEG quality of 100 all the time? That might be appropriate for images meant for high quality photo work, but usually you would save in a lossless file format such as PNG rather than JPEG. Most programs which save JPEG images allow the user to set the quality before saving. For general photo viewing, a quality of about 60-70 is usually considered good enough. If the file size is your priority, maybe you should settle on 70 as "best possible".
Right now I have it set to check the file size, and if the file size is above 245 KB to reduce the compression quality until the image is below the 245 KB. The reason the file must be a JPEG under 245 kb is so that I can use it as a to replace an OEM image of Windows that checks against the size before displaying an image. I also have the quality set elsewhere to around 70 unless the file is too large.
I do end up doing a test save, but it is directly to the disk rather than to the memory. If the file is too big after my resizing, I leave the old file and let the user know that the file didn't work as expected. I am new at programming, so I try and keep it simple.
Re: Resize Image from Picture box to predefined size (1080p)
Doing the test save to a MemoryStream (or maybe a FileStream) should be a bit quicker and save clutter on the disk. Probably it will be easier to stick to quality = 70 and reduce the pixel size of the image when necessary to keep the file size within limits. I'll see if I can work out some code tomorrow (W.Eu time) if no one else chips in first. BB