Click here to Skip to main content
15,881,803 members
Articles / Programming Languages / XML

Image Canvas Border Editor

Rate me:
Please Sign up or sign in to vote.
3.15/5 (3 votes)
18 Jan 2020CPOL2 min read 5.6K   180   1   1
Small tool for adding borders to image for canvas printing

Introduction

This is a simple tool that adds borders (edges) to a bitmap image to prepare it for printing on canvas. The edges are needed because the printed canvas picture is mounted onto wooden frames, so you need some extra edges to be able to attach it to the frame.

Here is an example that illustrates the principle:

Image 1

The tool gives you an opportunity to create solid color frames or mirror frames (which is better because the edges are more seamless and smoother after framing).

Using the Tool

The form consists of a PictureBox and some buttons underneath:

Image 2

  • Open - Opens an openFileDialog to choose the picture
  • Transform - Adds the frames; if Solid color checkbox is selected, then the frames shall be solid color, otherwise they shall be mirror edges. Frame thickness numericUpDown determines the thickness of the frame.
  • Save - Saves the result image; this button doesn't work if the Transform has not been done yet.

This is how an original and transformed image with mirror edges would look like:

Image 3

Image 4

The Code

The code is more or less quite standard stuff, there are several bitmap transformations that I would like to point out.

Original Image vs. Shown Image

The bitmap that is loaded stays saved in memory the whole time, original and intact. However, to be able to show the picture in the picturebox, it needs to be resized in case it is larger than the picturebox:

C#
private Bitmap resizePic(Bitmap original, float scale)
{
    if (scale == 1) return original;
    Bitmap bmp = new Bitmap((int)(original.Width * scale), (int)(original.Height * scale));
    Graphics g = Graphics.FromImage(bmp);
    g.InterpolationMode = InterpolationMode.High;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.DrawImage(original, new Rectangle(0, 0, (int)(original.Width * scale), 
               (int)(original.Height * scale)), new Rectangle(0, 0, original.Width, 
               original.Height), GraphicsUnit.Pixel);
    return bmp;
}

The scale is calculated as minimum of both ratios of widths and heights of the image against the picturebox:

C#
scale = Math.Min((float)pictureBox1.Width / (float)editPic.Width, 
                 (float)pictureBox1.Height / (float)editPic.Height);

Adding Frames

The method for adding the frames has two overloads - one for solid color and one for mirror edges.

The one that creates the mirror edges first adds a default (black) edge to the bitmap, and then copies certain parts of the original image to fill the edges, flipping the original image appropriately each time.

C#
private Bitmap addFrames(Bitmap original, int frameWidth)
{
    Bitmap bmp = addFrames(original, frameWidth, Color.Black);
    Bitmap retBmp = new Bitmap(bmp.Width, bmp.Height);
    Graphics g = Graphics.FromImage(retBmp);
    g.InterpolationMode = InterpolationMode.High;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    // draw original
    g.DrawImage(original, new Rectangle(frameWidth, frameWidth, 
                original.Width, original.Height), 
                new Rectangle(0, 0, original.Width, original.Height), GraphicsUnit.Pixel);
    // draw left and right frame
    original.RotateFlip(RotateFlipType.RotateNoneFlipX);
    g.DrawImage(original, new Rectangle(0, frameWidth, frameWidth, original.Height), 
                new Rectangle(original.Width - frameWidth, 0, frameWidth, original.Height), 
                GraphicsUnit.Pixel);
    g.DrawImage(original, new Rectangle(original.Width + frameWidth, frameWidth, 
                frameWidth, original.Height), 
                new Rectangle(0, 0, frameWidth, original.Height), GraphicsUnit.Pixel);
    original.RotateFlip(RotateFlipType.RotateNoneFlipX);
    // draw upper and lower frame
    original.RotateFlip(RotateFlipType.RotateNoneFlipY);
    g.DrawImage(original, new Rectangle(frameWidth, 0, original.Width, frameWidth), 
                new Rectangle(0, original.Height - frameWidth, original.Width, frameWidth), 
                GraphicsUnit.Pixel);
    g.DrawImage(original, new Rectangle(frameWidth, original.Height + frameWidth, 
                original.Width, frameWidth), new Rectangle(0, 0, original.Width, frameWidth), 
                GraphicsUnit.Pixel);
    original.RotateFlip(RotateFlipType.RotateNoneFlipY);
    // draw corners
    original.RotateFlip(RotateFlipType.RotateNoneFlipXY);
    g.DrawImage(original, new Rectangle(0, 0, frameWidth, frameWidth), 
                new Rectangle(original.Width - frameWidth, original.Height - frameWidth, 
                frameWidth, frameWidth), GraphicsUnit.Pixel);
    g.DrawImage(original, new Rectangle(original.Width + frameWidth, 0, 
                frameWidth, frameWidth), new Rectangle(0, original.Height - frameWidth, 
                frameWidth, frameWidth), GraphicsUnit.Pixel);
    g.DrawImage(original, new Rectangle(0, original.Height + frameWidth, 
                frameWidth, frameWidth), new Rectangle(original.Width - frameWidth, 0, 
                frameWidth, frameWidth), GraphicsUnit.Pixel);
    g.DrawImage(original, new Rectangle(original.Width + frameWidth, 
                original.Height + frameWidth, frameWidth, frameWidth), 
                new Rectangle(0, 0, frameWidth, frameWidth), GraphicsUnit.Pixel);
    original.RotateFlip(RotateFlipType.RotateNoneFlipXY);
    return retBmp;
}

private Bitmap addFrames(Bitmap original, int frameWidth, Color solidColor)
{
    int width = (int)(original.Width + 2 * frameWidth);
    int height = (int)(original.Height + 2 * frameWidth);
    Bitmap bmp = new Bitmap(width, height);
    Graphics g = Graphics.FromImage(bmp);
    g.InterpolationMode = InterpolationMode.High;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    var brush = new SolidBrush(solidColor);
    g.FillRectangle(brush, new RectangleF(0, 0, width, height));
    g.DrawImage(original, frameWidth, frameWidth, original.Width, original.Height);
    return bmp;
}

History

  • 18th January, 2020: Initial version

License

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


Written By
User Interface Analyst Raiffeisenbank Austria
Croatia Croatia
I acquired Masters degree in computing science at the Faculty of Electrical Engineering and Computing in Zagreb, Croatia in 2009. Following my studies, I got a job in a Croatian branch of Austrian-based CEE Raiffeisen Bank as an MIS (Management information system) analyst.
I have been working there since 2010, as an IT expert within the Controlling department, maintaining the Oracle's OFSA system, underlying interfaces and databases.
Throughout that time, I have worked with several different technologies, which include SQL & PL/SQL (mostly), postgres, Cognos BI, Apparo, Datastage, ODI, Jenkins, Qlik, ...
I am doing a lot of automation with scripting in batch / shell and VBscript (mostly) - data analysis and processing, automated DB imports and exports, Jenkins automation etc.
Privately, I was mostly doing Windows Forms and Console app tools in Visual Studio, C#.

Comments and Discussions

 
QuestionThanks Pin
robert1129-Mar-23 18:19
robert1129-Mar-23 18:19 

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

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