ZoomPictureBox: picture control with mouse-centred zooming
New version February 2019. See post #75 for details and zip files, and post #79 for a testing procedure.. The new version works much better with large images and includes a DragMargin property to prevent the image from being dragged out of view.
Introduction
This control offers easy zooming and dragging of any image. Out of the box, you can zoom the image with the mouse wheel and drag it with the left mouse button. But you can implement other ways of zooming and dragging in your code.
To whet your appetite, here's an illustration from the test project in the zip file:
The ZoomPictureBox has three different zoom modes. You can zoom to the centre of the control, to the centre of the image or to the mouse position. The last is my own favourite, so I have made it default.
You can set Image and the ZoomMode in the Designer or in your code. There are some other useful variables you can presently set only in your code. These include the minimum and maximum zoom sizes, and the MouseWheelDivisor which affects zooming speed with the mouse.
If you want to use some other way of controlling zoom, say a + and - button, set the control's EnableMouseWheelZooming to False, and change the ZoomFactor property in your code. The same applies to dragging; if required set EnableMouseDragging to false and implement some other way of dragging, for example with the arrow keys. In your code, you can move the image by setting the ImagePosition property.
Technical notes
1. I started off by inheriting from a PictureBox which explains the name. But I changed that later to a UserControl to save exposing unnecessary properties such as SizeMode and ImageSource.
2. The control works by changing the size and position of a rectangle (_ImageBounds). The image is rendered into the rectangle in the OnPaint sub.
3. Quite a few of the public fields could be usefully turned into properties which could be set in the designer. I will do that later that if there is enough interest.
4. The attached zip file is a complete solution (without the obj and bin folders and the dll file). It includes a demo Forms project. You should be able to unzip all the files and run the demo (I hope).
5. You can copy the ZoomPictureBox.vb file (in the ZoomPictureBox_Source folder) to use the control in your own projects.
6. Alternatively, you could give the ZoomPictureBox a permanent place in your ToolBox complete with its own icon . To do that:
a. check that the bitmap ZoomPictureBox.bmp has its Properties/Build Action set to Embedded Resource.
b. build the project
c. right click in the ToolBox and select Insert Items....
d. browse to the ZoomPictureBox_Build folder and select ZoomPictureBox.dll.
Last edited by boops boops; Jul 1st, 2019 at 10:54 AM.
Reason: New version February 2019.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
I built it using VB2010 with VB2008 in mind. I don't think there's anything in the code that won't compile under VB2005, but I don't have a copy to try it out. If nothing else helps I'm sure you could copy the all .VB files and the icon bitmap across to a new solution. The solution should have a Windows Forms project for the TestForm and a Class Library project for the rest. Make sure the Class Libary has references to System.Windows.Forms and System.Drawing. (You might need to reference System.ComponentModel as well, but I think it's included in Forms.) Maybe someone else knows an easier way. BB
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
@Boops. I converted it to vb2005. There's an error creating the form when you try to run the project with image = none + also the image remains displayed when you remove it at design time. Any idea what the problem is? Great control though.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Thanks for pointing out the problems Paul. I think I know how to fix them. I need to add
Code:
If _Image Is Nothing Then Return Rectangle.Empty
at the top of the GetZoomedBounds function, which otherwise needs the size of the image to do its work.
As for the image not clearing at design time, I can't reproduce the problem but I think I can see what might cause it. In the InitializeImage sub, I need to move Me.Invalidate outside the If _Image IsNot Nothing block so that the control will also be invalidated when the image is cleared.
I'll check these and if possible update the zip file tomorrow.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
I've updated the zip file in Post #1 with a few corrections and improvements. If you've added the control to your toolbox, please delete it then follow the steps in Post #1 (6a to 6d) again to reinstall it.
@.Paul. Would you be so kind as to update the VB2005 version?
Changes in ZoomPictureBox.vb:
1. Superfluous Imports statements removed.
2. Superfluous Shadows keyword removed from Image property.
3. In the ZoomFactor.Set, limited invalidation to the "before" and "after" rectangles. This improves performance when the BackgroundImage is set.
4. Ditto, in OnMouseMove sub.
5. In the InitializeImage sub, moved Invalidate outside the If block (see post #4).
6. In the GetZoomedBounds function, checked for existence of Image (see post #4).
New toolbox icon:
A bit more elegant, I hope you'll agree.
Changes in TestForm:
ZoomPictureBox.Anchor property set to "all sides" in Load event.
EDIT: I'm now unsure if the first version of the zip file actually included the test form. Well it does now!
Last edited by boops boops; Jul 12th, 2011 at 05:59 AM.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
I must be doing something wrong. I am running the VS2005 in debug mode and I am getting the following User Interface that is displayed within the attached file. Please help. Thank you. Bill
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Sorry for the bother. I've got it working. Very Cool Application. I will definitely add this to my library. I've been developing VB.net application for slightly over a year now. I am only a babe in the woods compared to you folks. My latest application was pretty intense mechanical engineering application for balancing the flow through a steam turbine and using a Newton-Raphson numerical method. I have a great understanding for the mathematics but with VS it is so complex and overwhelming at times. Thank God for the internet.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Originally Posted by .paul.
yeah that fixed it. here's a vb2005 version for you:
edit: updated all points in post #7 except the onMouseMove change because the image doesn't drag smoothly
Many thanks for the updated vb2005 version. I'm worried about the image not dragging smoothly, because I intended the changes to fix exactly that problem. Here's my current version of the OnMouseMove sub, in case you didn't get it from the latest zip file:
Code:
Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
If _dragging Then
Me.Invalidate(_ImageBounds) 'old position
_ImageBounds.X += e.X - _startDrag.X
_ImageBounds.Y += e.Y - _startDrag.Y
_startDrag = e.Location
Me.Invalidate(_ImageBounds) 'new position
End If
MyBase.OnMouseMove(e)
End Sub
If this doesn't fix it, would you please give me some more information. What is the size of the Image and BackgroundImage, and do they have (partly) transparent pixels? Are they photos or drawings? What is the size and BackgroundImageLayout of the ZoomPictureBox? Finally, it would help to know about your system: memory, graphics subsystem etc.
regards, BB
Last edited by boops boops; Jul 13th, 2011 at 03:13 AM.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
This is a great control. Gives me lots of possibilities... however... (why is there always one.. ?)
I've turned the vb into a dll and added to my app (vb2008). Now when I place the control on a form at default, location 0.0 it all works fine. When I move the control on the form, the mouse-focus shifts exponentially. So when I place the control on position 100.100 (size 200x200), I must use the mouse between 200.200 and 400.400 to zoom the image.
It's not the size of the control on the form, it's focused around the upper left position of the control, the mouse focus always starts twice the distance from the upper left position of the control. So the closer you keep it to the 0.0 of your form, the bigger the chances that you can keep your mouse on the image to scroll.
Any idea what I'm doing wrong? Is it a setting or a parameter I'm overlooking?
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Hi LDeeJay, welcome to VB forums. It's way past bedtime where I am, so I'll have a think about your problem tomorrow. Which mouse zooming mode are you using -- zoom to mouse position (the default), zoom to centre of image or zoom to centre of control?
I'm just opening the same pictures again and again... I haven't been able to pinpoint that one to a certain action or event, it seems a bit random at the moment.
Cheers,
Léon
Last edited by LDeeJay; Jan 13th, 2012 at 06:07 AM.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Hi Léon,
I just downloaded my own zip from post #1 and the zooming error you encountered is there large as life -- even in the test program! So thanks a lot for point it out. It's stupid I didn't notice it before (but neither did the 180 or so people who downloaded the code so far, or they didn't feel inclined to report it.) I will post a corrected version as soon as I have made sure it works correctly.
I'm puzzled by your other problem. I can cause an Overflow Exception by disabling the ZoomFactor validation and setting the MouseWheelDivisor to 1; but that's at a zoom factor of about 4 million. I assume you are not trying anything like that, but to be sure can you say what values you have for Image.Width and ZoomFactor (hover the mouse over the variable names when the error is thrown)?
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Zooming in and out works fine. At some point you can't zoom any further and that's fine. When the error occurs (most of the time just after starting the app), I haven't done any zooming/panning yet. The image is being loaded (an attempt is made) and at the moment it tries to stretch it in the control, it crashes.
The values:
_Image.Width=3872
_ImageBounds.Width = 0
-ImageBounds.Height=0
_ZoomFactor=0.077479338842975212
PreviousZoomFactor=0.0
zoomRatio=1.#INF
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Originally Posted by LDeeJay
Zooming in and out works fine. At some point you can't zoom any further and that's fine. When the error occurs (most of the time just after starting the app), I haven't done any zooming/panning yet. The image is being loaded (an attempt is made) and at the moment it tries to stretch it in the control, it crashes.
The values:
_Image.Width=3872
_ImageBounds.Width = 0
-ImageBounds.Height=0
_ZoomFactor=0.077479338842975212
PreviousZoomFactor=0.0
zoomRatio=1.#INF
Thanks. I can't reproduce the Overflow problem but your data has been helpful in taking a fresh look at the ZoomPictureBox code. I hope I have now made it more robust. Would you be so kind as to add the attached vb file to your project, rebuild and then try it instead of the existing ZoomPictureBox. Does it solve the overflow problem?
Meanwhile, I am still hunting for the cause of the mouse position problem. As far as I can see the only problem is that the wrong rectangle is raising MouseWheel events for the control. I have no idea why, so this may take a little time.
By the way, the maximum zoom factor is set to 32, but you can change it to any value. In the next version I will expose it as a Public Property.
BB
Last edited by boops boops; Dec 14th, 2021 at 10:00 AM.
Reason: obsolete code link deleted. See post #1 for current versions.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
The mousewheel problem is solved. What else could it be but the test in OnMouseWheel?
Code:
If EnableMouseWheelZooming AndAlso _
Me.Bounds.Contains(Me.PointToClient(MousePosition)) Then ...
Me.Bounds should have been Me.ClientRectangle. And PointToClient(MousePosition) can be replaced by e.Location. Credit to LDeeJay who spotted the problem at around the same time (private mail). I'll post a cleaned up version of the code soon.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
Fantastic job! Now on to my next challenge :-)
I want to zoom several images, which I can do now, and copy the contents of these controls into a new image. I can create a destination picture but... not with the result I want.
I've played around with FastPix, BitBlt and GetPixel but they all give me the result of the original picture that's loaded in ZoomPictureBox, not the zoomed picture so.... how can I copy the result of ZoomPictureBox into a new image?
Can anyone push me in the right direction? I'm using vb.net 2008.
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
There is another method capturing the image of a control as shown, the control's DrawToBitmap method, which works even when the control is partly or wholly hidden. However, I think that in the long run it is better to work as much as possible with the original images. The main reason is that the resolution is otherwise limited by the size of the controls, so you could lose quality when you work with larger images.
It's not difficult to superimpose one image on another without resorting to BitBlt etc. just by using DrawImage. The SuperimposeImage sub in the code below is an example. The ImagePosition and ZoomFactor properties of the ZoomPictureBox are useful here, as I intended. It takes a lot more work to get that kind of information from a normal picture box.
Anyway, to cut a long story short I decided to work out a little demo program for composing images. It could do with a lot of refinement but it should give you the idea. To use the code, start a form and add three buttons, a Picturebox and a ZoomPictureBox. Don't bother about setting the size or other properties of the two boxes because that is all dealt with in the code.
In use, Button1 opens a base image which is shown at full size; click cancel if you want an empty bitmap. Button 2 opens a zoomable/draggable image. Double-click the zoomed image to paint it onto the base image. Button3 saves the resulting image as a PNG or JPEG.
Here's a picture of the demo use:
And here's the code for the form:
vb Code:
Private _BaseImage As Image
Private _AddImage As Image
Public Property EmptyBitmapSize As New Size(500, 500)
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Re: ZoomPictureBox: picture control with mouse zooming (3 modes) and dragging
New version of ZoomPictureBox 20 January 2012. See post #22 above for info on the BB Image Composer demo application. Downloads are in post #1.
Summary of changes Bugs Fixed:
- Corrected faulty rectangle for detection of mouse wheel action.
- Code revised to prevent potential integer overflow.
New:
- New public read only property: ImageBounds.
- All public fields are now exposed as properties.
- Default values for MaximumZoom and Minimum Image Width/Height are changed.
- New demo application: BB Image Composer (see post #22 for details).
Technical modifications:
- The TestForm and demo application are placed in separate projects from the ZoomPictureBox itself.
- To keep the file sizes convenient, the ZoomPictureBox Class is split into two Partial Classes. One contains all the properties, the other everything else.
- The solution with demo is built in VB2005 and converts without change when loaded into VS2008 or VS2010.
I hope you like it! BB
Last edited by boops boops; Jan 19th, 2012 at 07:49 PM.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Hi Panesian,
Welcome to the VB Forums and thanks for your kind words. If you have questions (unless they are specifically about the ZoomPictureBox) please post them on the VB.Net forum.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Hi BB, I am new to this forum and to VB.NET, your application is brilliant. I am going to ask a question which is probably dumb, but I have to ask.
I start the BB Image Composer app, click on 'Open Base Image', I search for the picture I require, which is landscape picture of my daughter, it places the picture in app but I only see a small portion of the picture. The picture dimensions are; 4216 x 2968. So it is a large picture. What if any, do I need to do to get this particular picture to fit in the viewer?
Sorry if it sounds a dumb question but I just don't know.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Hi Steve,
In Load sub of the ImageComposer, I set the SizeMode of the base PictureBox (PictureBox1) to AutoSize. That means the picture box has the same size as the image. I did that to keep things simple -- after all, I meant it just a demo of how you can use a ZoomPictureBox, not a full-fledged application. Unfortunately, it's not much use for large images like your photo.
A simple answer is to use a smaller version of your photo. You could replace the first line of the Button1 Click sub by these lines:
Code:
Dim img As Image = GetImage(EmptyBitmapSize, "Select base image")
_BaseImge = New Bitmap(img, width, height)
Enter whatever positive values you like for width and height. It would be neater to declare the width and height as public properties so you can change them in the Designer (see the EmptyBitmapSize property for an example).
I'd like to redesign the whole program so that you could use different picture box size modes, or even another ZoomPictureBox for the base image. But that would make it quite a bit more complicated so it will have to wait for the while.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Thanks for your help, yes I will look at your suggestions, I can imagine how much more work would be involved. But yes the image is way too large, I will certainly reduce it's size.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Can you show me some simple code? I cant get it work. My image size is (800,600), my zoompicturebox size is (200,50). How can i display my image at certain zoom level and also at certain location of my image.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Try this in the Form Load sub or a Button Click sub. Play around with the numbers until you get the zoom size and position you want:
Code:
ZoomPictureBox1.ZoomFactor = 0.4
ZoomPictureBox1.ImagePosition = New Point(50, 60)
'If you want to leave the image fixed in that position, add these lines:
ZoomPictureBox1.EnableMouseWheelZooming = False
ZoomPictureBox1.EnableMouseDragging = False
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
Boops,
Thanks for the zoompicturebox, this is very usefull in my app, my users can enlarge blueprints to see details very well, any chance there's a way to print while the image is zoomed? Thanks again, this is really great control.
Last edited by OCD Dan; Apr 24th, 2012 at 03:31 PM.
Re: ZoomPictureBox: picture control with mouse zooming - NEW VERSION JAN 2012
You have your original image and you can get an enlarged detail as a separate image (see post #30). If you don't know how to print an image, please ask on the VB.Net forum. BB
Re: ZoomPictureBox: picture control with mouse-centred zooming
How would I go about adding a zoom in and zoom out button in addition to the mouse scroll function? For the standard picturebox, what I see people doing is just changing the size of the picturebox itself and I am trying to utilize the zoompicturebox here and add the button function to it without changing the size of the control every time. I am really new to VB.net and this is part of what I am doing to learn the language.