We help IT Professionals succeed at work.

Change DPI and/or Graphic File Dimensions Using ASP.NET and VB.NET

David Bach
David Bach asked
on
Greetings:

I have a client who currently is able to upload graphic file(s) to his website for display. My client is a restaurant owner and, as I believe most clients would agree, does not want to be bogged down with graphic file size do to DPI or dimensions of the the graphic.

I use VB.NET and Visual Studio Pro 2017.

I would like to manipulate the DPI and graphic dimensions for him. What I need to adjust are:
  • DPI
  • width or length keeping the aspect ratio of the graphic

I am not savvy when it comes to graphic files. I do know how to gain addressability to the graphic file IO stream after upload.

I need mentoring on how to do these two things and save the graphic file as a smaller version of itself.

Any assistance is greatly appreciated.


Much thanks,
David Bach
Comment
Watch Question

Chief Technology Ninja
Distinguished Expert 2019
Commented:
Hi David,

For the DPI part, it is simple, you can use Bitmap.SetResolution method. https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.setresolution?view=netframework-4.7.2

I am more than happy if you need clarification on DPI part.

For your second query, I was thinking to write my own explanation but then a quick search gave me this code snippet from : https://www.encodedna.com/2014/07/how-to-resize-an-image-using-aspdotnet-without-losing-quality.htm

Markup
<!DOCTYPE html>
<html>
<head>
    <title>Resize Image using Asp.Net</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:FileUpload 
                ID="UploadFile" 
                multiple="false" 
                runat="server" 
                BorderStyle="None" />

            <input type="button" 
                value="Upload Image" 
                id="button" 
                onserverclick="Resize" 
                runat="server" />
        
            <div id="Info" runat="server" style="padding:20px 0;"></div>
        </div>
    </form>
</body>
</html>

Open in new window


Codebehind
Option Explicit On
Imports System.IO
Imports System.Drawing

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Resize(ByVal sender As Object, ByVal e As EventArgs)

        ' GET THE UPLOADED FILE.
        Dim hfc As HttpFileCollection = Request.Files
        If hfc.Count > 0 Then

            Dim hpf As HttpPostedFile = hfc(0)
            If hpf.ContentLength > 0 Then

                Dim sImageName As String = hpf.FileName

                ' FIRST SAVE THE FILE ON THE SERVER.
                hpf.SaveAs(Server.MapPath("~/" & Path.GetFileName(sImageName)))

                ' ORIGINAL WIDTH AND HEIGHT.
                Dim bitmap As New Bitmap(Server.MapPath("~/" & Path.GetFileName(hpf.FileName)))

                Dim iwidth As Integer = bitmap.Width
                Dim iheight As Integer = bitmap.Height
                bitmap.Dispose()

                ' SHOW DETAILS OF ORIGINAL IMAGE WITH SIZE.
                Info.InnerHtml = "<b>Original Image</b> "
                Info.InnerHtml = Info.InnerHtml & "<br /> Width: " & iwidth & ", Height: " & iheight & "<br /> " & _
                    Double.Parse(hpf.ContentLength / 1024).ToString("N0") & " KB <br>"

                ' ONCE WE GOT ALL THE INFORMATION, WE'll NOW PROCESS IT.

                ' CREATE AN IMAGE OBJECT USING ORIGINAL WIDTH AND HEIGHT.
                ' ALSO DEFINE A PIXEL FORMAT (FOR RICH RGB COLOR).

                Dim objOptImage As System.Drawing.Image = _
                    New System.Drawing.Bitmap(iwidth, iheight, _
                        System.Drawing.Imaging.PixelFormat.Format16bppRgb555)

                ' GET THE ORIGINAL IMAGE.
                Using objImg As System.Drawing.Image = _
                    System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath("~/" & sImageName))

                    ' RE-DRAW THE IMAGE USING THE NEWLY OBTAINED PIXEL FORMAT.
                    Using oGraphic As System.Drawing.Graphics = 
                            System.Drawing.Graphics.FromImage(objOptImage)
                        With oGraphic
                            Dim oRectangle As New System.Drawing.Rectangle(0, 0, iwidth, iheight)

                            .DrawImage(objImg, oRectangle)
                        End With
                    End Using

                    ' SAVE THE OPTIMIZED IMAGE.
                    objOptImage.Save(HttpContext.Current.Server.MapPath("~/images/" & sImageName), _
                        System.Drawing.Imaging.ImageFormat.Png)

                    objImg.Dispose()
                End Using

                objOptImage.Dispose()

                ' FINALLY SHOW THE OPTIMIZED IMAGE DETAILS WITH SIZE.
                Dim bitmap_Opt As New Bitmap(Server.MapPath("~/images/" & Path.GetFileName(sImageName)))

                Dim iwidth_Opt As Integer = bitmap_Opt.Width
                Dim iheight_Opt As Integer = bitmap_Opt.Height
                bitmap_Opt.Dispose()

                ' FOR SIZE.
                Dim OptImgInfo As New FileInfo(Server.MapPath("~/images/" & Path.GetFileName(sImageName)))
                Dim ifileSize As Integer = OptImgInfo.Length    ' GET THE SIZE IN BYTES.

                Info.InnerHtml = Info.InnerHtml & "<br / ><b>Optimized Image</b>"
                Info.InnerHtml = Info.InnerHtml & "<br /> Width: " & iwidth_Opt & ", Height: " & iheight_Opt
                Info.InnerHtml = Info.InnerHtml & "<br /><span style=color:green>" & _
                    Double.Parse(ifileSize / 1024).ToString("N0") & " KB</span>"
            End If
        End If
    End Sub
End Class

Open in new window


You can see that most important statement is the one where he chooses another pixel format to redraw the image.
The one with PixelFormat.Format16bppRgb555). You can also use other techniques using Smoothing and Interpolation Modes to achieve similar or for smaller images, better results.

Regards,
Chinmay.
David BachPartner

Author

Commented:
Greetings Chimnay:

I was able to use both your suggestions to obtain the results for my client!

I did make changes to the code behind as follows:
  • Changed the objOptImage object from Image to Bitmap so I could change the resolution
  • Added code to ensure the longest side was 600px and the smaller side was adjusted appropriately
  • Removed the Format16bppRgb555 when creating a new Bitmap

My code behind with changes follows.
Imports System.IO
Imports System.Drawing

Partial Class Graphic
	Inherits System.Web.UI.Page

	Protected Sub Resize(ByVal sender As Object, ByVal e As EventArgs)

		' GET THE UPLOADED FILE.
		Dim hfc As HttpFileCollection = Request.Files

		If hfc.Count > 0 Then

			Dim hpf As HttpPostedFile = hfc(0)

			If hpf.ContentLength > 0 Then

				Dim sImageName As String = hpf.FileName

				' FIRST SAVE THE FILE ON THE SERVER.
				hpf.SaveAs(Server.MapPath("~/" & Path.GetFileName(sImageName)))

				' ORIGINAL WIDTH AND HEIGHT.
				Dim bitmap As New Bitmap(Server.MapPath("~/" & Path.GetFileName(hpf.FileName)))

				Dim iwidth As Integer = bitmap.Width
				Dim iheight As Integer = bitmap.Height

				bitmap.Dispose()

				' SHOW DETAILS OF ORIGINAL IMAGE WITH SIZE.
				Info.InnerHtml = "<b>Original Image</b> "
				Info.InnerHtml = Info.InnerHtml & "<br /> Width: " & iwidth & ", Height: " & iheight & "<br /> " &
					Double.Parse(hpf.ContentLength / 1024).ToString("N0") & " KB <br>"

				' ONCE WE GOT ALL THE INFORMATION, WE'll NOW PROCESS IT.

				' CREATE AN IMAGE OBJECT USING ORIGINAL WIDTH AND HEIGHT.
				' ALSO DEFINE A PIXEL FORMAT (FOR RICH RGB COLOR).

				Dim intSavedHeight As Int32 = iheight
				Dim intSavedWidth As Int32 = iwidth

				If iwidth > iheight Then
					iwidth = 600
					iheight = Convert.ToSingle((iwidth / intSavedWidth) * iheight)
				Else
					iheight = 600
					iwidth = Convert.ToSingle((iheight / intSavedHeight) * iwidth)
				End If

				Dim objOptImage As Bitmap =
					New Bitmap(iwidth, iheight)
				objOptImage.SetResolution(72, 72)

				' GET THE ORIGINAL IMAGE.
				Using objImg As Image =
					Image.FromFile(Server.MapPath("~/" & sImageName))

					' RE-DRAW THE IMAGE USING THE NEWLY OBTAINED PIXEL FORMAT.
					Using oGraphic As Graphics =
							Graphics.FromImage(objOptImage)

						With oGraphic

							Dim oRectangle As New Rectangle(0, 0, iwidth, iheight)

							.DrawImage(objImg, oRectangle)
						End With

					End Using

					' SAVE THE OPTIMIZED IMAGE.
					objOptImage.Save(HttpContext.Current.Server.MapPath("~/Images/" & sImageName),
						Imaging.ImageFormat.Jpeg)

					objImg.Dispose()
				End Using

				objOptImage.Dispose()

				' FINALLY SHOW THE OPTIMIZED IMAGE DETAILS WITH SIZE.
				Dim bitmap_Opt As New Bitmap(Server.MapPath("~/images/" & Path.GetFileName(sImageName)))

				Dim iwidth_Opt As Integer = bitmap_Opt.Width
				Dim iheight_Opt As Integer = bitmap_Opt.Height

				bitmap_Opt.Dispose()

				' FOR SIZE.
				Dim OptImgInfo As New FileInfo(Server.MapPath("~/images/" & Path.GetFileName(sImageName)))
				Dim ifileSize As Integer = OptImgInfo.Length    ' GET THE SIZE IN BYTES.

				Info.InnerHtml = Info.InnerHtml & "<br / ><b>Optimized Image</b>"
				Info.InnerHtml = Info.InnerHtml & "<br /> Width: " & iwidth_Opt & ", Height: " & iheight_Opt
				Info.InnerHtml = Info.InnerHtml & "<br /><span style=color:green>" &
					Double.Parse(ifileSize / 1024).ToString("N0") & " KB</span>"
			End If

		End If

	End Sub

End Class

Open in new window

Much thanks for your help, Chinmay!

David Bach
Chinmay PatelChief Technology Ninja
Distinguished Expert 2019

Commented:
Glad I could help David.