Click here to Skip to main content
Click here to Skip to main content

Image Magnifier Control

, 11 Oct 2006
Rate this:
Please Sign up or sign in to vote.
ImageMagnifier - a simple control for image zooming.

Sample Image - ImageMagnifier.gif

Introduction

The well known PictureBox control, often used in .NET Windows Forms applications is a very useful and complex control, allowing us to display graphical information. But no one is perfect, and PictureBox has its own disadvantages. One of them, I confronted, is a blur zooming. When you try to zoom some small-size picture, it looks like an illegible blur. So, I decided to write a simple control for image zooming, and call it ImageMagnifier.

Using the code

The ImageMagnifier is a WinForms control and can be used like any other control. Just add a reference to the ImageMagnifier.dll assembly in new project. Then, you can add the control to your form by dragging it from the Visual Studio Toolbox, or you can create it programmatically using code like this:

ImageMagnifier.ImageMagnifier imageMagnifier = 
                  new ImageMagnifier.ImageMagnifier(); 
this.Controls.Add(imageMagnifier);

The ImageMagnifier has a ImageToMagnify property, which corresponds to an Image class. You can set it using the Properties window in your project, or programmatically:

imageMagnifier.ImageToMagnify = Image.FromFile("SomeImage.jpg");

Then, you have to set the MagnificationCoefficient property. It is an Int32 value, with a value range of 1 to 64:

imageMagnifier.MagnificationCoefficient = 10;

That is all you need to do. After running your application, you will see a defined image, zoomed in MagnificationCoefficient times.

How it works

The proposed control is pretty simple. It derives from the Control class and overrides the OnPaint method. The image associated with ImageMagnifier is represented as a two dimensional Int32 array of pixels (ImageMagnifier.pixels). This array fills with colors of the corresponding pixels each time the user defines the ImageToMagnify property:

public Image ImageToMagnify
{
    get { return imageToMagnify; }
    set 
    {
        if (value != null)
        {
            imageToMagnify = value;
            Bitmap b = new Bitmap(this.ImageToMagnify);

            pixels = new int[this.ImageToMagnify.Width, 
                             this.ImageToMagnify.Height];

            for (int i = 0; i < this.ImageToMagnify.Width; i++)
                for (int j = 0; j < this.ImageToMagnify.Height; j++)
                {
                    pixels[i, j] = b.GetPixel(i, j).ToArgb();
                }
            this.Invalidate();
        }
    }
}

The OnPaint method is as follows:

protected override void OnPaint(PaintEventArgs pe)
{
    if (imageToMagnify != null)
    {
        this.Width = imageToMagnify.Width * magnificationCoefficient;
        this.Height = imageToMagnify.Height * magnificationCoefficient;

        int currentTop = 0;
        int currentLeft = 0;
        for (int i = 0; i < this.ImageToMagnify.Width; i++)
        {
            currentTop = i * magnificationCoefficient;
            for (int j = 0; j < this.ImageToMagnify.Height; j++)
            {
                currentLeft = j * magnificationCoefficient;
                Brush b = new SolidBrush(Color.FromArgb(pixels[i, j]));
                pe.Graphics.FillRectangle(b, currentTop, currentLeft, 
                magnificationCoefficient, magnificationCoefficient);
            }
        }
    }
}

So, every time the control calls the OnPaint method, it draws a rectangles for each pixel from the pixels array. The dimension of each rectangle is determined by the MagnificationCoefficient property.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Bashir Magomedov
Software Developer (Senior)
United Kingdom United Kingdom
Work: HSBC (http://www.hsbc.co.uk/).
Regalia: PhD in CS, MCAD, MCPD: Web Developer, MCTS: .Net Framework 2.0., 3.5.
Interests: Programming, artificial intelligence, C#, .NET, HTML5, ASP.NET, SQL, LINQ.
Marital Status: Married, daughter
Blog: http://www.magomedov.co.uk

Comments and Discussions

 
GeneralPerformance PinmemberElGuroProgramador21-Oct-06 7:06 
GeneralRe: Performance PinprofessionalEd Gadziemski2-Mar-14 8:47 
GeneralTry this! PinmemberAugustoRuiz11-Oct-06 4:25 
GeneralRe: Try this! PinmemberBashir Magomedov11-Oct-06 6:03 
GeneralRe: Try this! PinmemberAugustoRuiz11-Oct-06 7:03 
Ok... You can check out the BitmapData class in System.Drawing.Imaging Wink | ;)
 
With this class you can update image data (or get image data) really fast. A sample:
 
        private int[] GetPixelsFromImage(Image img)
        {
            int[] pixels;
            BitmapData bmData = ((Bitmap)img).LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, img.PixelFormat);
            
            pixels = new int[img.Width * img.Height];
 
            IntPtr bmDataPtr = bmData.Scan0;
            int arrayIndex = 0;
 
            for (int line = 0; line < img.Height; line++)
            {
                System.Runtime.InteropServices.Marshal.Copy(bmDataPtr, pixels, arrayIndex, img.Width);
 
                // Advance pointers to the next line.
                bmDataPtr += bmData.Stride;
                arrayIndex += img.Width;
            }
 
            ((Bitmap)img).UnlockBits(bmData);
 
            return pixels;
        }
 
Of course this is valid if the image is a 32BPP image... (one int is one pixel). Although I'd use a byte[] to ensure I can get the bitmap data whatever the format, and to access single pixels you can take into account how many bytes does each pixel take (you can find out the BITS per pixel using Bitmap.GetPixelFormatSize(img.PixelFormat)).
 
Why do I use the loop for copying? Because of the way images can be stored, a line of data can take more memory than the count of bytes of its representation. So you have the Stride property in BitmapData class to know how many bytes does each line take in real memory. Wink | ;)
GeneralRe: Try this! [modified] Pinmemberfirmwaredsp11-Oct-06 9:26 
GeneralRe: Try this! PinmemberAugustoRuiz11-Oct-06 22:58 
GeneralRe: Try this! Pinmemberrajantawate1(http//www.jhatak.com)4-Oct-07 9:19 
GeneralRe: Try this! PinmemberM i s t e r L i s t e r10-Feb-13 6:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 11 Oct 2006
Article Copyright 2006 by Bashir Magomedov
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid