skip to Main Content

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


  1. I haven’t tested, but I think you should be using a different variable in this line of code.

    g.DrawImage(bmp, New Rectangle(0, 0, bm.Width, bm.Height),
                             CropArea,
                             GraphicsUnit.Pixel)
    
    Login or Signup to reply.
  2. You have a typo caused by using variable names that are too similar. As written, you have this block of code:

    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
    

    This line:

    g.DrawImage(bm, 
                New Rectangle(0, 0, bm.Width, bm.Height),
                CropArea,
                GraphicsUnit.Pixel)
    

    Should be:

    g.DrawImage(bmp, 
                New Rectangle(0, 0, bm.Width, bm.Height),
                CropArea,
                GraphicsUnit.Pixel)
    

    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 object g 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search