I just wanted to share this piece of code with everybody.
I had the need to zoom in and out of the video player, but the class does not support this feature yet, and did not actually find anything in the forums, so i decided to implement it myself. If there is a better piece of code out there, please share it with all of us.
I am working with the version 2.1.0 of the framework.
To do this, I had to modify the Aforge.Conntrols.VideoSourcePlayer class as follows:
Firts, add two variables to store the zoom and zoom location
- Code: Select all
public float zoomFactor = 1;
private Point zoomPosition = new Point(0, 0);
Then modify the callback for the OnPaint control --> VideoSourcePlayer_Paint
- Code: Select all
// Paint control
private void VideoSourcePlayer_Paint( object sender, PaintEventArgs e )
{
// is it required to update control's size/position
if ( ( needSizeUpdate ) || ( firstFrameNotProcessed ) )
{
UpdatePosition( );
needSizeUpdate = false;
}
lock ( this )
{
Graphics g = e.Graphics;
Rectangle rect = this.ClientRectangle;
Pen borderPen = new Pen( borderColor, 1 );
// draw rectangle
g.DrawRectangle( borderPen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1 );
if ( videoSource != null )
{
if ( ( currentFrame != null ) && ( lastMessage == null ) )
{
int width = (int)(this.Width * this.zoomFactor);
int height = (int)(this.Height * this.zoomFactor);
float x = (rect.Width < width) ? (this.zoomPosition.X * (-1) * (this.zoomFactor - 1)) : (rect.Width - width) / 2;
float y = (rect.Height < height) ? (this.zoomPosition.Y * (-1) * (this.zoomFactor - 1)): (rect.Height - height) / 2;
// draw current frame
g.DrawImage(currentFrame, x, y, width, height);
//Original line
//g.DrawImage(currentFrame, rect.X + 1, rect.Y + 1, rect.Width - 2, rect.Height - 2 );
firstFrameNotProcessed = false;
}
else
{
// create font and brush
SolidBrush drawBrush = new SolidBrush( this.ForeColor );
g.DrawString( ( lastMessage == null ) ? "Connecting ..." : lastMessage,
this.Font, drawBrush, new PointF( 5, 5 ) );
drawBrush.Dispose( );
}
}
borderPen.Dispose( );
}
}
And add a function that actually sets the two variables:
- Code: Select all
public void Zoom(float zoomFactor, Point zoomPoint)
{
this.zoomFactor = zoomFactor;
this.zoomPosition = zoomPoint;
}
There are also magnification limits, but i handle that on the form that contains the control itself.
Now, to zoom into the frame, just call the function from the form that contains the control as follows:
Note that i capture the mouse position with the MouseEventArgs
- Code: Select all
private void videoSourcePlayer1_Click(object sender, EventArgs e)
{
MouseEventArgs arg = (MouseEventArgs)e;
if (this.btZoomIn.Checked == true)
{
float zoom = this.videoSourcePlayer1.zoomFactor * 2;
if (zoom > 10) zoom = 10F; //maximum value is 10
//minimum value is 0.2
this.videoSourcePlayer1.Zoom(zoom, arg.Location);
}
else if (this.btZoomOut.Checked == true)
{
float zoom = this.videoSourcePlayer1.zoomFactor / 2;
if (zoom < 0.2) zoom = 0.2F; //minimum value is 0.2
this.videoSourcePlayer1.Zoom(zoom, arg.Location);
}
}
Note that in my code, I also have 2 buttons, one to zoom in and another one to zoom out and they get checked when clicked (only one checked at the same time).
When the mouse enters and leaves the video source control the mouse pointer gets sets with a zoom_in/ zoom_out pic and defualt pointer accordingly, which is gives the customer some kind of feed back on what he is trying to do.
- Code: Select all
private void videoSourcePlayer1_MouseEnter(object sender, EventArgs e)
{
if (this.btZoomIn.Checked == true)
{
IntPtr ptr = Resources.zoom_in.GetHicon();
Cursor c = new Cursor(ptr);
this.Cursor = c;
}
else if (this.btZoomOut.Checked == true)
{
IntPtr ptr = zoom_out.GetHicon();
Cursor c = new Cursor(ptr);
this.Cursor = c;
}
}
private void videoSourcePlayer1_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Default;
}
I will try to implement the pan function of it as well, i will post it when ready.
Hope it helps
Regards