Problems changing image resolution in VB.NET

K

kombu67

I'm reading a series of images from a MS SQL table and saving them to
directory. These are staff ID pictures from our security card app.
Once I've extracted the ID photo from the security app to disk, I need
to reference the disk file in our HR app. As part of the process, I'm
resizing the image and changing its resolution from 96 to 72 dpi. If
they are not at a 72 dpi resolution, the HR app freezes. The resizing
works without a hitch, but I cannot figure out how to reduce the
resolution. All of the output files continue to be 96 dpi. Any help
would be greatly appreciated.

Here's the code

<snip...>
Dim bytImage() As Byte
bytImage = .ItemArray(4)
bytImage = ChangeImageResolution(bytImage, 72)
bytImage = ResizeImage(bytImage, 150)
Dim fs As New FileStream(strFileName, FileMode.OpenOrCreate,
FileAccess.Write)
fs.Write(bytImage, 0, UBound(bytImage))
fs.Close()
fs = Nothing
<snip...>
Private Function ChangeImageResolution(ByVal bytInput As Byte(), ByVal
intOutputResolution As Int16) As Byte()
Dim strmInput As New System.IO.MemoryStream(bytInput)
Dim strmOutput As New System.IO.MemoryStream
Dim imgInput As System.Drawing.Image
Dim imgOutput As System.Drawing.Image
Dim bmapTemp As Bitmap

' Create a temporary bitmap and set to output resolution
imgInput = System.Drawing.Image.FromStream(strmInput)
bmapTemp = imgInput
bmapTemp.SetResolution(intOutputResolution, intOutputResolution)
imgOutput = New Bitmap(bmapTemp)
imgOutput.Save(strmOutput,
System.Drawing.Imaging.ImageFormat.Jpeg)

' Return the output image in a byte array
ChangeImageResolution = strmOutput.ToArray
End Function
Private Function ResizeImage(ByVal bytInput As Byte(), ByVal
intFinalMaxDim As Int16) As Byte()
Dim strmInput As New System.IO.MemoryStream(bytInput)
Dim strmOutput As New System.IO.MemoryStream
Dim imgInput As System.Drawing.Image
Dim imgOutput As System.Drawing.Image
Dim intMaxDim As Int16 = 0
Dim dblResizePercentage As Double = 0
Dim sizResize As New Size

' Determine the resizing percentage based on current image
dimensions
imgInput = System.Drawing.Image.FromStream(strmInput)
If imgInput.Height >= imgInput.Width Then
intMaxDim = imgInput.Height
Else
intMaxDim = imgInput.Width
End If
dblResizePercentage = (intFinalMaxDim / intMaxDim)
With sizResize
.Width = CInt(imgInput.Width * dblResizePercentage)
.Height = CInt(imgInput.Height * dblResizePercentage)
End With

' Create a new resized version of the image
imgOutput = New Bitmap(imgInput, sizResize.Width,
sizResize.Height)
imgOutput.Save(strmOutput,
System.Drawing.Imaging.ImageFormat.Jpeg)

' Return the output image in a byte array
ResizeImage = strmOutput.ToArray
End Function
 
A

Armin Zingler

I'm reading a series of images from a MS SQL table and saving them
to directory. These are staff ID pictures from our security card
app. Once I've extracted the ID photo from the security app to disk,
I need to reference the disk file in our HR app. As part of the
process, I'm resizing the image and changing its resolution from 96
to 72 dpi. If they are not at a 72 dpi resolution, the HR app
freezes. The resizing works without a hitch, but I cannot figure out
how to reduce the resolution. All of the output files continue to be
96 dpi. Any help would be greatly appreciated.

imgInput = System.Drawing.Image.FromStream(strmInput)
bmapTemp = imgInput

I guess you know that the line above only copies the reference, not the
image. (?) (but that's not the problem, see below)
bmapTemp.SetResolution(intOutputResolution, intOutputResolution)
imgOutput = New Bitmap(bmapTemp)
imgOutput.Save(strmOutput,
System.Drawing.Imaging.ImageFormat.Jpeg)


You should set the resolution of the new bitmap (imgOutput):

imgOutput = New Bitmap(bmapTemp)
imgOutput.SetResolution(intOutputResolution, intOutputResolution)


Armin
 
K

kombu67

You should set the resolution of the new bitmap (imgOutput):

imgOutput = New Bitmap(bmapTemp)
imgOutput.SetResolution(intOutputResolution, intOutputResolution)

Armin

Armin,

Thanks for your reply. I was trying to convert imgInput from a
System.Drawing.Image (imgInput) to a Bitmap (bmapTemp), then use the
SetResolution method, and finally convert bmapTemp back to a
System.Drawing.Image (imgOutput).

I've tried your suggestion of using SetResolution on imgOutput, but it
doesn't work because imgOutput is a System.Drawing.Image object.

Have I misunderstood you?
 
A

Armin Zingler

Armin,

Thanks for your reply. I was trying to convert imgInput from a
System.Drawing.Image (imgInput) to a Bitmap (bmapTemp), then use the
SetResolution method, and finally convert bmapTemp back to a
System.Drawing.Image (imgOutput).

I've tried your suggestion of using SetResolution on imgOutput, but
it doesn't work because imgOutput is a System.Drawing.Image object.

Have I misunderstood you?

I didn't see that imtOutput is declared as Image. You can declare it As
Bitmap because it's always a Bitmap in the code you posted.


Armin
 
K

kombu67

I didn't see that imtOutput is declared asImage. You can declare it As
Bitmap because it's always a Bitmap in the code you posted.

Armin- Hide quoted text -

- Show quoted text -

Armin,

Thanks for your message. I see your point about the imgOutput object.
When I dimension imgOutput as a bitmap and examine the result in the
Watch window, it is a bitmap object with a 72 dpi resolution.

Apparently I'm not understanding the System.Drawing.Image.Save method.
The result of these lines is a byte array containing a 96 dpi jpeg.

imgOutput.Save(strmOutput,
System.Drawing.Imaging.ImageFormat.Jpeg)
' Return the output image in a byte array
ResizeImage = strmOutput.ToArray

Do you have any suggestions of how to translate the 72 dpi bitmap to a
72 dpi jpeg?
 
A

Armin Zingler

Armin,

Thanks for your message. I see your point about the imgOutput
object. When I dimension imgOutput as a bitmap and examine the
result in the Watch window, it is a bitmap object with a 72 dpi
resolution.

Apparently I'm not understanding the System.Drawing.Image.Save
method. The result of these lines is a byte array containing a 96
dpi jpeg.

imgOutput.Save(strmOutput,
System.Drawing.Imaging.ImageFormat.Jpeg)
' Return the output image in a byte array
ResizeImage = strmOutput.ToArray

Do you have any suggestions of how to translate the 72 dpi bitmap to
a 72 dpi jpeg?

Aaahh, another thing I didn't see. You're clandestinly converting to a JPG
when saving. ;-) I did some research but didn't find how to do it. I only
know how to specify the compression quality and other parameters but not the
resolution. Maybe m.p.dotnet.framework.drawing has an answer.


Armin
 
K

kombu67

Aaahh, another thing I didn't see. You're clandestinly converting to a JPG
when saving. ;-) I did some research but didn't find how to do it. I only
know how to specify the compression quality and other parameters but not the
resolution. Maybe m.p.dotnet.framework.drawing has an answer.

Armin- Hide quoted text -

- Show quoted text -

Thanks, Armin. I really appreciate your help with this. I'll try the
m.p.dotnet.framework.drawing group as you suggest.
 
G

Guest

You can convert to a bitmap then back to a JPEG using Codecs. With the
bitmap you might try:

Dim bm As New Bitmap
'Convert your image using Codecs into bm
bm.SetResolution(72, 72)
bm.Save("C:\test1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
or
bm.SetResolution(100, 100)
bm.Save("C:\test2.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)

Using Codecs allows control over image quality, etc. also. An example of
Codec usage:

Public Class CvImage

Shared codecs() As ImageCodecInfo

Public Sub New()
'Get the list of available encoders
Static Init As Boolean = True
If Init Then codecs = ImageCodecInfo.GetImageEncoders() : Init = False
End Sub
Public Function BitMapToJpeg(ByVal img As Image, Optional ByVal quality
As Integer = 100) As Image
Dim ici As ImageCodecInfo
For Each codec As ImageCodecInfo In codecs
If (codec.MimeType = "image/jpeg") Then
ici = codec
End If
Next
Dim ep As EncoderParameters = New EncoderParameters(1)
'Set Quality Parameter
ep.Param(0) = New EncoderParameter(Encoder.Quality, Quality)
'Save to a Memory Stream
Dim s As New System.IO.MemoryStream
' Dim byt() As Byte
img.Save(s, ici, ep)
Return img.FromStream(s)
End Function
Public Function ImageToJpegToBytes(ByVal img As Image, Optional ByVal
Quality As Integer = 100) As Byte()
'find the encoder with the image/jpeg mime-type
Dim ici As ImageCodecInfo
For Each codec As ImageCodecInfo In codecs
If (codec.MimeType = "image/jpeg") Then
ici = codec
End If
Next
Dim ep As EncoderParameters = New EncoderParameters(1)
'Set Quality Parameter
ep.Param(0) = New EncoderParameter(Encoder.Quality, Quality)
'Save to a Memory Stream
Dim s As New System.IO.MemoryStream
Dim byt() As Byte
img.Save(s, ici, ep)
'Convert Memory Stream to byte array
Return s.ToArray
End Function
End Class


If you can't work something with the above, you might try something along
the following:
- Create graphics object with the DPIX and DPIY you want of the pixel size
of the image
- Use BitBlt to copy your bitmap into the graphics object

Just some ideas that might work....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top