I want to resize an image to a max width and height and then crop it.
The resizing works. But the cropping code I found here does not.
My own existing code uses a byte array, so I need to work with that.
So the code below does resize, does NOT crop, and does save the new image. What am I doing wrong with the cropping?
Dim imgNewWidth, imgNewHeight As Integer
Dim _originalThumbWidth As Integer = 900
Dim _originalThumbHeight As Integer = 900
Dim imageURL As String = "https://med.stanford.edu/news/all-news/2021/09/cat-fur-color-patterns/_jcr_content/main/image.img.780.high.jpg/cat_by-Kateryna-T-Unsplash.jpg"
Dim localImagePath As String = Server.MapPath("images_tmp") + "CROPPED.jpg"
ResizeAndSaveFast(_originalThumbWidth, _originalThumbHeight, imageURL, localImagePath, "", "", imgNewWidth, imgNewHeight)
Private Function ResizeAndSaveFast(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal imageURL As String, ByVal saveToPath As String, ByVal userName As String, ByVal password As String,
ByRef imgNewWidth As Integer, ByRef imgNewHeight As Integer) As Boolean
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim imgRequest As WebRequest = WebRequest.Create(imageURL)
Dim imgResponse As WebResponse
Dim memStream As New MemoryStream
Try
imgResponse = imgRequest.GetResponse()
Dim streamPhoto As Stream = imgResponse.GetResponseStream()
streamPhoto.CopyTo(memStream)
memStream.Position = 0
Catch ex As Exception
Return False
End Try
Dim bfPhoto As BitmapFrame = ReadBitmapFrame(memStream)
Dim newWidth, newHeight As Integer
Dim scaleFactor As Double
newWidth = bfPhoto.PixelWidth
newHeight = bfPhoto.PixelHeight
imgNewWidth = newWidth
imgNewHeight = newHeight
If bfPhoto.PixelWidth > maxWidth Or bfPhoto.PixelHeight > maxHeight Then
If bfPhoto.PixelWidth > maxWidth Then
scaleFactor = maxWidth / bfPhoto.PixelWidth
newWidth = CInt(Math.Round(bfPhoto.PixelWidth * scaleFactor, 0))
newHeight = CInt(Math.Round(bfPhoto.PixelHeight * scaleFactor, 0))
End If
If newHeight > maxHeight Then
scaleFactor = maxHeight / newHeight
newWidth = CInt(Math.Round(newWidth * scaleFactor, 0))
newHeight = CInt(Math.Round(newHeight * scaleFactor, 0))
End If
End If
imgNewWidth = newWidth
imgNewHeight = newHeight
Dim bfResize As BitmapFrame = FastResize(bfPhoto, newWidth, newHeight)
Dim baResize As Byte() = ToByteArray(bfResize)
Dim bmp As System.Drawing.Bitmap = imageFunctions.ConvertByteArrayToBitmap(baResize)
Dim CropArea As Rectangle = New Rectangle(100, 100, bmp.Width - 100, bmp.Height - 100)
Dim bm As Bitmap = New Bitmap(CropArea.Width, CropArea.Height)
Using g As Graphics = Graphics.FromImage(bm)
g.DrawImage(bm, New Rectangle(0, 0, bm.Width, bm.Height),
CropArea,
GraphicsUnit.Pixel)
End Using
bm.Save(saveToPath, ImageFormat.Jpeg)
Return True
End Function
2
Answers
I haven’t tested, but I think you should be using a different variable in this line of code.
You have a typo caused by using variable names that are too similar. As written, you have this block of code:
This line:
Should be:
In your code, you created the variable
bmp
to store the non-cropped bitmap. In other words, your source data.You then declare
bm
to store the cropped bitmap, your destination. The Graphics objectg
is created using the destination.in your call to
g.DrawImage
, the first argument should be the source data,bmp
. Instead you have the destination,bm
there.