.NET Image Viewer Example

This is a simple example of working with images with the .NET Framework. It saves images in other formats, prints, print previews, etc. Download the complete source code: DOTNETIMGVIEWER.zip

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Drawing.Drawing2D;
using System.Collections.Generic;

namespace ImageViewer
{
	internal class SelectionDialog : Form
	{
		private ImageViewer parent;
		public SelectionDialog(ImageViewer iv)
		{
			ClientSize = new Size(155, 100);
			ShowInTaskbar = false;
			MaximizeBox = false;
			MinimizeBox = false;
			FormBorderStyle = FormBorderStyle.FixedDialog;
			CenterToScreen();
			parent = iv;
			NumericUpDown nud = new NumericUpDown();
			nud.Parent = this;
			nud.Minimum = 1;
			nud.Maximum = 128;
			nud.Value = iv.penWidth;
			nud.Location = new Point(75, 5);
			nud.Size = new Size(45, Font.Height + 4);
			nud.LostFocus += new EventHandler(nudPenWidth_LostFocus);
			Label lbl = new Label();
			lbl.Parent = this;
			lbl.Text = "Pen Width:";
			lbl.Location = new Point(3, 7);
			lbl.Size = new Size(80, Font.Height);
			HScrollBar hsb = new HScrollBar();
			hsb.Parent = this;
			hsb.Minimum = 0;
			hsb.Maximum = 255;
			hsb.Value = iv.alpha;
			hsb.Location = new Point(75, 35);
			hsb.Size = new Size(75, Font.Height + 4);
			hsb.ValueChanged += new EventHandler(hsbAlpha_ValueChanged);
			lbl = new Label();
			lbl.Parent = this;
			lbl.Text = "Transparency:";
			lbl.Location = new Point(3, 37);
			lbl.Size = new Size(80, Font.Height);
		}

		void hsbAlpha_ValueChanged(object sender, EventArgs e)
		{
			parent.alpha = (byte)((HScrollBar)sender).Value;
		}

		void nudPenWidth_LostFocus(object sender, EventArgs e)
		{
			parent.penWidth = (int)((NumericUpDown)sender).Value;
		}
	}
	class ImageViewer : Form
	{
		private Image[] img = { null, null };
		private int scrollX, scrollY;
		public byte alpha;
		public int penWidth;
		private Point ptLast;
		private Bitmap bmHelp;
		private string filename;
		private TextBox txt;
		private ToolBar tb;
		private bool bEnableDrawing, bTracking;
		private PrintDocument pdoc = new PrintDocument();
		private PrintDialog pdlg = new PrintDialog();
		private PageSetupDialog psdlg = new PageSetupDialog();
		private PrintPreviewDialog prdlg = new PrintPreviewDialog();
		private ColorDialog clrdlg = new ColorDialog();

		[STAThread]
		static void Main()
		{
			Application.Run(new ImageViewer());
		}
		public ImageViewer()
		{
			Text = "Image Viewer";
			BackColor = Color.Black;
			ForeColor = Color.Black;
			Width = 600;
			Height = 450;
			AutoScroll = true;

			bEnableDrawing = false;
			scrollX = scrollY = 0;
			bTracking = false;
			penWidth = 1;
			alpha = 255;

			txt = new TextBox();
			txt.Parent = this;
			txt.Multiline = false;
			txt.Dock = DockStyle.Top;
			txt.Text = "http://www.google.com/images/srpr/logo11w.png [press enter]";
			txt.Visible = false;
			txt.KeyDown += new KeyEventHandler(txt_KeyDown);
			txt.BackColor = Color.FromKnownColor(KnownColor.ButtonFace);
			txt.BorderStyle = BorderStyle.FixedSingle;

			pdoc.PrintPage += new PrintPageEventHandler(pdoc_PrintPage);
			pdlg.Document = pdoc;
			psdlg.Document = pdoc;
			prdlg.Document = pdoc;

			Menu = new MainMenu();
			Menu.MenuItems.Add("&Image");
			Menu.MenuItems.Add("&View");
			Menu.MenuItems.Add("&Drawing");
			Menu.MenuItems.Add("&Help");
			Menu.MenuItems[0].Popup += new EventHandler(MenuImage_Popup);
			Menu.MenuItems[0].MenuItems.Add("Open from &Internet...", FromInternetOnClick);
			Menu.MenuItems[0].MenuItems.Add("&Open...", FromFileOnClick);
			Menu.MenuItems[0].MenuItems.Add("Save &As...", SaveAsOnClick);
			Menu.MenuItems[0].MenuItems.Add("&Print...", MenuPrintOnClick);
			Menu.MenuItems[0].MenuItems.Add("Print Pre&view...", MenuPrintPreviewOnClick);
			Menu.MenuItems[0].MenuItems.Add("Page &Setup...", MenuPageSetupOnClick);
			Menu.MenuItems[0].MenuItems.Add("&Copy to Clipboard", MenuCopyOnClick);
			Menu.MenuItems[0].MenuItems.Add("Paste from &Clipboard", MenuPasteOnClick);
			Menu.MenuItems[1].MenuItems.Add("&Toolbar", MenuToolbarOnClick);
			Menu.MenuItems[1].MenuItems[0].Checked = false;
			Menu.MenuItems[2].Popup += new EventHandler(MenuDrawing_Popup);
			Menu.MenuItems[2].MenuItems.Add("&Enable Drawing", MenuEnableDrawingOnClick);
			Menu.MenuItems[2].MenuItems.Add("Select &Color...", MenuSelectColorOnClick);
			Menu.MenuItems[2].MenuItems.Add("&Select Pen Width and Transparency...", MenuSelectPenOnClick);
			MenuItem mi = new MenuItem("&Undo", MenuUndoOnClick);
			mi.Shortcut = Shortcut.CtrlZ;
			Menu.MenuItems[2].MenuItems.Add(mi);
			mi = new MenuItem("&Help");
			mi.OwnerDraw = true;
			mi.Click += new EventHandler(miHelp_Click);
			mi.MeasureItem += new MeasureItemEventHandler(miHelp_MeasureItem);
			mi.DrawItem += new DrawItemEventHandler(miHelp_DrawItem);
			Menu.MenuItems[3].MenuItems.Add(mi);
			bmHelp = new Bitmap(this.GetType(), "Help.bmp");

			//create image list for toolbar
			Bitmap bm = new Bitmap(this.GetType(), "Toolbar.bmp");
			ImageList imglist = new ImageList();
			imglist.Images.AddStrip(bm);
			imglist.TransparentColor = Color.Fuchsia;

			//create toolbar
			tb = new ToolBar();
			tb.Parent = this;
			tb.Visible = false;
			tb.ImageList = imglist;
			tb.ShowToolTips = true;
			tb.BorderStyle = BorderStyle.None;
			tb.ButtonClick += new ToolBarButtonClickEventHandler(tb_ButtonClick);
			ToolBarButton tbb = new ToolBarButton();
			tbb.Style = ToolBarButtonStyle.Separator;
			tb.Buttons.Add(tbb);
			string[] strs = { "From the Internet", "From a File" };
			for (int i = 0; i <= strs.GetUpperBound(0); i++)
			{
				tbb = new ToolBarButton();
				tbb.ImageIndex = i;
				tbb.ToolTipText = strs[i];
				tbb.Tag = Menu.MenuItems[0].MenuItems[i];
				tb.Buttons.Add(tbb);
			}
		}

		void MenuDrawing_Popup(object sender, EventArgs e)
		{
			Menu.MenuItems[2].MenuItems[0].Enabled = (img[0] != null);
			Menu.MenuItems[2].MenuItems[1].Enabled = (bEnableDrawing && img[0] != null);
			Menu.MenuItems[2].MenuItems[2].Enabled = (bEnableDrawing && img[0] != null);
			Menu.MenuItems[2].MenuItems[3].Enabled = (img[0] != null && img[1] != null);
		}

		void miHelp_DrawItem(object sender, DrawItemEventArgs e)
		{
			Rectangle rect = e.Bounds;
			rect.X += e.Bounds.Width - bmHelp.Width;
			rect.Width = bmHelp.Width;
			e.DrawBackground();
			e.Graphics.DrawImage(bmHelp, rect);
		}

		void miHelp_MeasureItem(object sender, MeasureItemEventArgs e)
		{
			e.ItemWidth = bmHelp.Width;
			e.ItemHeight = bmHelp.Height;
		}

		void miHelp_Click(object sender, EventArgs e)
		{
			MessageBox.Show("Keep praying... maybe help will come.", "Help System");
		}
		private void MenuSelectPenOnClick(object obj, EventArgs e)
		{
			SelectionDialog dlg = new SelectionDialog(this);
			dlg.ShowDialog();
		}
		private void MenuUndoOnClick(object obj, EventArgs e)
		{
			Image tmp = img[0];
			img[0] = img[1];
			img[1] = tmp;
			Invalidate();
		}
		private void MenuEnableDrawingOnClick(object obj, EventArgs e)
		{
			bEnableDrawing = !bEnableDrawing;
			((MenuItem)obj).Checked = bEnableDrawing;
			this.AutoScrollMinSize = new Size(img[0].Width, img[0].Height);
			Invalidate();
		}
		private void MenuSelectColorOnClick(object obj, EventArgs e)
		{
			clrdlg.Color = ForeColor;
			if (clrdlg.ShowDialog() == DialogResult.OK)
				ForeColor = clrdlg.Color;
		}
		private void MenuCopyOnClick(object obj, EventArgs e)
		{
			Clipboard.SetImage(img[0]);
		}
		private void MenuPasteOnClick(object obj, EventArgs e)
		{
			img[0] = Clipboard.GetImage();
			this.Invalidate();
		}
		protected override void OnMouseDown(MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left || img[0] == null || bEnableDrawing == false) return;
			ptLast = new Point(e.X, e.Y);
			bTracking = true;
			img[1] = new Bitmap(img[0]);
		}
		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (!bTracking || img[0] == null) return;
			
			Point ptNew = new Point(e.X, e.Y);
			if (ptNew.X < img[0].Width && ptNew.Y < img[0].Height)
			{
				Pen pen = new Pen(Color.FromArgb(alpha, ForeColor), penWidth);
				Brush br = new SolidBrush(Color.FromArgb(alpha, ForeColor));
				using (Graphics g = CreateGraphics())
				{
					g.SmoothingMode = SmoothingMode.HighQuality;
					g.DrawLine(pen, ptLast, ptNew);
					if (penWidth > 1)
					{
						g.FillEllipse(br, ptLast.X - penWidth / 2, ptLast.Y - penWidth / 2, penWidth, penWidth);
						g.FillEllipse(br, ptNew.X - penWidth / 2, ptNew.Y - penWidth / 2, penWidth, penWidth);
					}
				}
				Graphics gi = Graphics.FromImage(img[0]);
				gi.SmoothingMode = SmoothingMode.HighQuality;
				Point ptLast2 = new Point(ptLast.X + scrollX, ptLast.Y + scrollY);
				Point ptNew2 = new Point(ptNew.X + scrollX, ptNew.Y + scrollY);
				gi.DrawLine(pen, ptLast2, ptNew2);
				if (penWidth > 1)
				{
					gi.FillEllipse(br, ptLast2.X - penWidth / 2, ptLast2.Y - penWidth / 2, penWidth, penWidth);
					gi.FillEllipse(br, ptNew2.X - penWidth / 2, ptNew2.Y - penWidth / 2, penWidth, penWidth);
				}
			}
			ptLast = ptNew;
		}
		protected override void OnMouseUp(MouseEventArgs e)
		{
			bTracking = false;
			Invalidate();
		} 
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			if (img[0] != null)
			{
				if (!bEnableDrawing)
				{
					RectangleF rectf = this.ClientRectangle;
					ScaleIsotropically(e.Graphics, img[0], rectf);
				}
				else
				{
					e.Graphics.DrawImage(img[0], new Rectangle(-scrollX, -scrollY, img[0].Width, img[0].Height));
				}
			}
		}
		void pdoc_PrintPage(object sender, PrintPageEventArgs e)
		{
			Graphics g = e.Graphics;
			RectangleF rectf = new RectangleF(e.MarginBounds.Left - (e.PageBounds.Width - g.VisibleClipBounds.Width) / 2, 
				e.MarginBounds.Top - (e.PageBounds.Height - g.VisibleClipBounds.Height) / 2, 
				e.MarginBounds.Width, 
				e.MarginBounds.Height);
			ScaleIsotropically(g, img[0], rectf);
		}
		private void ScaleIsotropically(Graphics g, Image imgIn, RectangleF rectf)
		{
			SizeF szf = new SizeF(imgIn.Width / imgIn.HorizontalResolution, imgIn.Height / imgIn.VerticalResolution);
			float scale = Math.Min(rectf.Width / szf.Width, rectf.Height / szf.Height);
			szf.Width *= scale;
			szf.Height *= scale;
			g.DrawImage(imgIn, rectf.X + (rectf.Width - szf.Width) / 2, rectf.Y + (rectf.Height - szf.Height) / 2, szf.Width, szf.Height);
		}

		void MenuImage_Popup(object sender, EventArgs e)
		{
			Menu.MenuItems[0].MenuItems[2].Enabled =
				Menu.MenuItems[0].MenuItems[3].Enabled =
				Menu.MenuItems[0].MenuItems[4].Enabled =
				Menu.MenuItems[0].MenuItems[6].Enabled = (img[0] != null);
			Menu.MenuItems[0].MenuItems[7].Enabled = (Clipboard.GetImage() != null);
		}
		void DownloadImageThread()
		{
			Cursor cur = this.Cursor;
			this.Cursor = Cursors.WaitCursor;
			try
			{
				WebRequest wreq = WebRequest.Create(txt.Text.Replace("[press enter]", "").Trim());
				WebResponse wres = wreq.GetResponse();
				using (Stream st = wres.GetResponseStream())
				{
					img[1] = null;
					img[0] = Image.FromStream(st);
					st.Close();
					txt.Visible = false;
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message.ToString() + "\r\n\r\n" + txt.Text.Replace("[press enter]", ""), Text);
			}
			filename = null;
			this.Invalidate();
			this.Cursor = cur;
		}
		void txt_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Return)
			{
				Thread t = new Thread(DownloadImageThread);
				t.Start();
			}
		}

		void tb_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
		{
			ToolBarButton tbb = e.Button;
			MenuItem mi = (MenuItem)tbb.Tag;
			mi.PerformClick();
		}
		private void FromInternetOnClick(object obj, EventArgs e)
		{
			txt.Visible = true;
			txt.Focus();
		}
		private void FromFileOnClick(object obj, EventArgs e)
		{
			txt.Visible = false;
			OpenFileDialog ofd = new OpenFileDialog();
			ofd.Filter = "Images|*.bmp;*.png;*.gif;*.jpg;*.jpeg;*.jfif;*.tif;*.tiff;*.wmf;*.emf";
			ofd.CheckFileExists = true;
			ofd.ReadOnlyChecked = true;
			ofd.ShowReadOnly = true;
			ofd.RestoreDirectory = true;
			if (ofd.ShowDialog() == DialogResult.OK)
			{
				filename = ofd.FileName;
				try
				{
					img[1] = null;
					img[0] = Image.FromFile(filename);
				}
				catch (Exception ex)
				{
					MessageBox.Show(ex.Message.ToString() + "\r\n\r\n" + filename, Text);
					filename = null;
					img[0] = null;
				}
				this.Invalidate();
			}
		}
		private void MenuToolbarOnClick(object obj, EventArgs e)
		{
			tb.Visible = !tb.Visible;
			Menu.MenuItems[1].MenuItems[0].Checked = tb.Visible;
		}
		private void MenuPageSetupOnClick(object obj, EventArgs e)
		{
			psdlg.ShowDialog();
		}
		private void SaveAsOnClick(object obj, EventArgs e)
		{
			if (img[0] != null)
			{
				SaveFileDialog sfd = new SaveFileDialog();
				if (filename != null)
					sfd.InitialDirectory = Path.GetDirectoryName(filename);
				sfd.FileName = (filename == null) ? "Untitled" : Path.GetFileNameWithoutExtension(filename);
				sfd.AddExtension = true;
				sfd.Filter = "BMP|*.bmp|GIF|*.gif|JPEG|*.jpg;*.jpeg|PNG|*.png|TIFF|*.tif;*.tiff";

				ImageFormat[] ifs ={ ImageFormat.Bmp, ImageFormat.Gif, ImageFormat.Jpeg, ImageFormat.Png, ImageFormat.Tiff };

				if (sfd.ShowDialog() == DialogResult.OK)
				{
					try
					{
						img[0].Save(sfd.FileName, ifs[sfd.FilterIndex - 1]);
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message, Text);
						return;
					}
					filename = sfd.FileName;
				}
			}
		}
		private void MenuPrintOnClick(object obj, EventArgs e)
		{
			if (pdlg.ShowDialog() == DialogResult.OK)
			{
				pdoc.DocumentName = Text;
				pdoc.Print();
			}
		}
		private void MenuPrintPreviewOnClick(object obj, EventArgs e)
		{
			prdlg.ShowDialog();
		}
		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);
			if(!bEnableDrawing)
				this.Invalidate();
		}
		protected override void OnScroll(ScrollEventArgs se)
		{
			if (se.ScrollOrientation == ScrollOrientation.HorizontalScroll)
			{
				scrollX = se.NewValue;
			}
			else if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
			{
				scrollY = se.NewValue;
			}
			this.Invalidate();
		}
	}
}