Creating a scrollable and zoomable image viewer in C# Part 1
This is the first part in a series of articles that will result in a component for viewing an image. The final component will support zooming and scrolling.
In this first part, we're going to create a basic image viewer, without the scrolling and zooming. Rather than having a plain background however, we're going to create a two tone checker box effect which is often used for showing transparent images. We'll also allow this to be disabled and a solid colour used instead.
Creating the component
The component inherits from Control
rather than something
like PictureBox
or Panel
as we want to provide a lot of
our own behaviour.
The first thing we'll do is override some properties - to hide
the ones we won't be using such as Text
and Font
, and to
modify others, such as making AutoSize
visible, and changing
the default value of BackColor
.
Next is to add some new properties. We'll create the following properties and respective change events:
BorderStyle
- A standard border style.GridCellSize
- The basic cell size.GridColor
andGridColorAlternate
- The colors used to create the checkerboard style background.GridScale
- A property for scaling theGridCellSize
for user interface options.Image
- The image to be displayed.ShowGrid
- Flag to determine if the checkerboard background should be displayed.
As we are offering auto size support, we also override some existing events so we can resize when certain actions occur, such as changing the control's padding or parent.
Setting control styles
As well as setting up default property values, the component's constructor also adjusts several control styles.
AllPaintingInWmPaint
- We don't need a separateOnPaintBackground
andOnPaint
mechanism,OnPaint
will do fine.UserPaint
- As we are doing entirely our own painting, we disable the base Control's painting.OptimizedDoubleBuffer
- Double buffering means the painting will occur in a memory buffer before being transferred to the screen, reducing flicker.ResizeRedraw
- Automatically redraw the component if it is resized.Selectable
- We disable this flag as we don't want the control to be receiving focus.
public ImageBox()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer| ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, false);
this.UpdateStyles();
this.BackColor = Color.White;
this.TabStop = false;
this.AutoSize = true;
this.GridScale = ImageBoxGridScale.Small;
this.ShowGrid = true;
this.GridColor = Color.Gainsboro;
this.GridColorAlternate = Color.White;
this.GridCellSize = 8;
this.BorderStyle = BorderStyle.FixedSingle;
}
Creating the background
The CreateGridTileImage
method creates a tile of a 2x2 grid
using many of the properties listed above which is then tiled
across the background of the control.
protected virtual Bitmap CreateGridTileImage(int cellSize, Color firstColor, Color secondColor)
{
Bitmap result;
int width;
int height;
float scale;
// rescale the cell size
switch (this.GridScale)
{
case ImageBoxGridScale.Medium:
scale = 1.5F;
break;
case ImageBoxGridScale.Large:
scale = 2;
break;
default:
scale = 1;
break;
}
cellSize = (int)(cellSize * scale);
// draw the tile
width = cellSize * 2;
height = cellSize * 2;
result = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(result))
{
using (SolidBrush brush = new SolidBrush(firstColor))
g.FillRectangle(brush, new Rectangle(0, 0, width, height));
using (SolidBrush brush = new SolidBrush(secondColor))
{
g.FillRectangle(brush, new Rectangle(0, 0, cellSize, cellSize));
g.FillRectangle(brush, new Rectangle(cellSize, cellSize, cellSize, cellSize));
}
}
return result;
}
Painting the control
As described above, we've disabled all default painting, so we
simply need to override OnPaint
and do our custom painting
here.
protected override void OnPaint(PaintEventArgs e)
{
if (_gridTile != null && this.ShowGrid)
{
// draw the background
for (int x = 0; x < this.ClientSize.Width; x += _gridTile.Size.Width)
{
for (int y = 0; y < this.ClientSize.Height; y += _gridTile.Size.Height)
e.Graphics.DrawImageUnscaled(_gridTile, x, y);
}
}
else
{
using (SolidBrush brush = new SolidBrush(this.BackColor))
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
// draw the image
if (this.Image != null)
{
e.Graphics.DrawImageUnscaled(this.Image, new Point(this.Padding.Left + this.GetBorderOffset(), this.Padding.Top + this.GetBorderOffset()));
}
// draw the borders
switch (this.BorderStyle)
{
case BorderStyle.FixedSingle:
ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, this.ForeColor, ButtonBorderStyle.Solid);
break;
case BorderStyle.Fixed3D:
ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, Border3DStyle.Sunken);
break;
}
}
First, we either draw a solid background using the BackColor
property if ShowGrid
is false
, otherwise we tile the grid
image created earlier.
Next we draw the actual image, if one has been set. The image is offset based on the border style and padding.
Finally we draw the border style to ensure it appears on top of the image if autosize is disabled and the control is too small.
Sample Project
You can download the first sample project from the links below. The next article in the series will look at implementing scrolling for when the image is larger than the display area of the control.
Update History
- 2010-08-12 - First published
- 2020-11-21 - Updated formatting
Related articles you may be interested in
- Displaying multi-page tiff files using the ImageBox control and C#
- Adding drag handles to an ImageBox to allow resizing of selection regions
- ImageBox 1.1.4.0 update
- ImageBox and TabList update's - virtual mode, pixel grid, bug fixes and more!
- ImageBox update, version 1.1.0.0
- Zooming to fit a region in a ScrollableControl
- Zooming into a fixed point on a ScrollableControl
- Arcade explosion generator
- Creating an image viewer in C# Part 5: Selecting part of an image
- Extending the ImageBox component to display the contents of a PDF file using C#
- Creating a scrollable and zoomable image viewer in C# Part 4
- Creating a scrollable and zoomable image viewer in C# Part 3
- Creating a scrollable and zoomable image viewer in C# Part 2
Downloads
Filename | Description | Version | Release Date | |
---|---|---|---|---|
imageboxsample-part-1.zip
|
First in a multi part series on creating an image viewer that can be scrolled and zoomed in C#. |
12/08/2010 | Download |
Leave a Comment
While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?
Comments
aligh
#
thank you
Geovanni Akra
#
great