I have been trying to calculate the right side of my rectangle so that it avoids mouse going over a specific area within a picture box. This works fine when zoom factor is 1, after zoom is increased right side becomes smaller than the Picturebox's width hence I can not move the mouse over the whole Picturebox area (this also happens when calculating the bottom of rectangle)
This is the code I have written, any help would be appreciated. PIC_SMALL_CLICK_1 function is where I do the calculations please advise, Thanks
This is the code I have written, any help would be appreciated. PIC_SMALL_CLICK_1 function is where I do the calculations please advise, Thanks
Public Class Form1 Private selectedArea As Rectangle Private loadedImage As Image Private thumbnail As Image Private selectionColor As Color Public Sub New() InitializeComponent() loadedImage = picSmall.Image 'the zoom area in the thumbnail selectedArea = New Rectangle(0, 0, 80, 60) tZoom.Value = 1 resizePictureArea() updateZoom() frmMagnifier.Show() End Sub ''' <summary> ''' Stretches out a selected zoom area of an image ''' </summary> Private Function ZoomImage(ByVal input As Image, ByVal zoomArea As Rectangle, ByVal sourceArea As Rectangle) As Image Dim newBmp As New Bitmap(sourceArea.Width, sourceArea.Height) Using g As Graphics = Graphics.FromImage(newBmp) 'high interpolation g.InterpolationMode = InterpolationMode.HighQualityBicubic g.DrawImage(input, sourceArea, zoomArea, GraphicsUnit.Pixel) End Using Return newBmp End Function ''' <summary> ''' Draws the selection rectangle on an image ''' </summary> Private Function MarkImage(ByVal input As Image, ByVal selectedArea As Rectangle, ByVal selectColor As Color) As Image Dim newImg As New Bitmap(input.Width, input.Height) Using g As Graphics = Graphics.FromImage(newImg) 'Prevent using images internal thumbnail input.RotateFlip(RotateFlipType.Rotate180FlipNone) input.RotateFlip(RotateFlipType.Rotate180FlipNone) g.DrawImage(input, 0, 0) 'Draw the selection rect Using p As New Pen(Brushes.Black, 4) g.DrawRectangle(p, selectedArea) End Using End Using Return DirectCast(newImg, Image) End Function ''' <summary> ''' Resizes an image ''' </summary> Private Function ResizeImage(ByVal input As Image, ByVal newSize As Size, ByVal interpolation As InterpolationMode) As Image Dim newImg As New Bitmap(newSize.Width, newSize.Height) Using g As Graphics = Graphics.FromImage(newImg) 'Prevent using images internal thumbnail input.RotateFlip(RotateFlipType.Rotate180FlipNone) input.RotateFlip(RotateFlipType.Rotate180FlipNone) 'Interpolation g.InterpolationMode = interpolation 'Draw the image with the new dimensions g.DrawImage(input, 0, 0, newSize.Width, newSize.Height) End Using Return DirectCast(newImg, Image) End Function ''' <summary> ''' Calculates the opposite color of a given color. ''' Source: ''' </summary> ''' <param name="clr"></param> ''' <returns></returns> Private Function CalculateOppositeColor(ByVal clr As Color) As Color Return Color.FromArgb(255 - clr.R, 255 - clr.G, 255 - clr.B) End Function ''' <summary> ''' Constricts a set of given dimensions while keeping aspect ratio. ''' </summary> Private Function ShrinkToDimensions(ByVal originalWidth As Integer, ByVal originalHeight As Integer, ByVal maxWidth As Integer, ByVal maxHeight As Integer) As Size Dim newWidth As Integer = 0 Dim newHeight As Integer = 0 If originalWidth >= originalHeight Then 'Match area width to max width If originalWidth <= maxWidth Then newWidth = originalWidth newHeight = originalHeight Else newWidth = maxWidth newHeight = originalHeight * maxWidth \ originalWidth End If Else 'Match area height to max height If originalHeight <= maxHeight Then newWidth = originalWidth newHeight = originalHeight Else newWidth = originalWidth * maxHeight \ originalHeight newHeight = maxHeight End If End If Return New Size(newWidth, newHeight) End Function Private Sub resizePictureArea() 'Create a thumbnail image (maintaining aspect ratio) Dim newSize As Size = ShrinkToDimensions(loadedImage.Width, loadedImage.Height, 160, 130) 'use low interpolation 'thumbnail = ResizeImage(loadedImage, New Size(newSize.Width, newSize.Height), InterpolationMode.Low) thumbnail = ResizeImage(loadedImage, New Size(picSmall.Width, picSmall.Height), InterpolationMode.Low) picSmall.Invalidate() End Sub Private Sub updateZoom() If loadedImage IsNot Nothing Then 'Map the area selected in the thumbail to the actual image size Dim zoomArea As New Rectangle() zoomArea.X = selectedArea.X * loadedImage.Width / thumbnail.Width zoomArea.Y = selectedArea.Y * loadedImage.Height / thumbnail.Height zoomArea.Width = selectedArea.Width * loadedImage.Width / thumbnail.Width zoomArea.Height = selectedArea.Height * loadedImage.Height / thumbnail.Height 'Adjust the selected area to the current zoom value zoomArea.Width /= tZoom.Value zoomArea.Height /= tZoom.Value frmMagnifier.picZoom.Image = ZoomImage(loadedImage, zoomArea, frmMagnifier.picZoom.ClientRectangle) frmMagnifier.picZoom.Refresh() End If End Sub Private Sub tZoom_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tZoom.Scroll updateZoom() End Sub Private Sub picSmall_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles picSmall.Click 'Update the selected area when the user clicks on the thumbnail Dim mouseLoc As Point = picSmall.PointToClient(Cursor.Position) selectedArea.X = mouseLoc.X - ((selectedArea.Width / tZoom.Value) / 2) selectedArea.Y = mouseLoc.Y - ((selectedArea.Height / tZoom.Value) / 2) 'Bound the box to the picture area bounds If selectedArea.Left < 0 Then selectedArea.X = 0 ElseIf selectedArea.Right > picSmall.Width Then selectedArea.X = picSmall.Width - selectedArea.Width - 1 End If If selectedArea.Top < 0 Then selectedArea.Y = 0 ElseIf selectedArea.Bottom > picSmall.Height Then selectedArea.Y = picSmall.Height - selectedArea.Height - 1 End If picSmall.Invalidate() updateZoom() End Sub Private Sub picSmall_Paint_1(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picSmall.Paint If loadedImage IsNot Nothing Then 'Adjust the selected area to reflect the zoom value Dim adjustedArea As New Rectangle() adjustedArea.X = selectedArea.X adjustedArea.Y = selectedArea.Y adjustedArea.Width = selectedArea.Width / tZoom.Value adjustedArea.Height = selectedArea.Height / tZoom.Value 'Draw the selected area on the thumbnail picSmall.Image = MarkImage(thumbnail, adjustedArea, selectionColor) End If End Sub End Class