Lecture 8 Building an MDI Application. Introduction The MDI (Multiple Document Interface) provides a...

10
Lecture 8 Building an MDI Application

Transcript of Lecture 8 Building an MDI Application. Introduction The MDI (Multiple Document Interface) provides a...

Lecture 8Building an MDI Application

Introduction

The MDI (Multiple Document Interface) provides a way to display multiple (child) windows forms inside a single main (parent) windows form.

In this example we will build an MDI application for image processing called...

Image Blaster 9000A brief overview of the features:

Open and Save images of type - jpg, gif, and bmp

Copy/Pase images from one child window to another.

Incorporate an existing class of image filters.

Apply various image manipulation filters e.g. grayscale, binary, posterize, erode, laplacian...

using System;using System.Drawing;using System.Drawing.Imaging;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;

namespace ImageBlaster9000{ public struct PixelData { public byte blue; public byte green; public byte red; }

public unsafe class ImgPro { Bitmap bitmap; int width; BitmapData bitmapData = null; Byte* pBase = null;

public ImgPro(Bitmap bitmap) { this.bitmap = bitmap; }

public void Save(string filename) { bitmap.Save(filename, ImageFormat.Jpeg); }

public void Dispose() { bitmap.Dispose(); }

public Bitmap Bitmap { get { return (bitmap); } }

public Point PixelSize{ get { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF bounds = bitmap.GetBounds(ref unit); return new Point((int)bounds.Width, (int)bounds.Height); }}

public void GrayScale(){ Point size = PixelSize; LockBitmap(); for (int x = 0; x < size.X; x++) { for (int y = 0; y < size.Y; y++) { PixelData* pPixel = PixelAt(x, y); int value = (pPixel->red + pPixel->green + pPixel->blue) / 3; pPixel->red = (byte)value; pPixel->green = (byte)value; pPixel->blue = (byte)value; } } UnlockBitmap();}

The Fast Image Processing Class - ImgPro

The properties in this class make use of static memory byte-arrays to speed up pixel-level processing. These techniques are implemented in the PixelAt( ), LockBitmap( ), and UnlockBitmap( ) methods.

The ImgPro Class is available on the course Web page.

public void LockBitmap() { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF boundsF = bitmap.GetBounds(ref unit); Rectangle bounds = new Rectangle((int)boundsF.X, (int)boundsF.Y, (int)boundsF.Width, (int)boundsF.Height); width = (int)boundsF.Width * sizeof(PixelData); if (width % 4 != 0) width = 4 * (width / 4 + 1); bitmapData = bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); pBase = (byte*)bitmapData.Scan0.ToPointer(); }

public PixelData* PixelAt(int x, int y) { return (PixelData*)(pBase + y * width + x * sizeof(PixelData)); }

public void UnlockBitmap() { bitmap.UnlockBits(bitmapData); bitmapData = null; pBase = null; } }}

LockBitmap( ), PixelAt( ), and UnlockBitmap( )

Permitting your Program to Run in Unsafe Mode

open the Properties Page - not the Properties Window or Properties Panel or Properties Drop down Menu Item or ...

Properties Page

check the "All unsafe code" checkbox

public partial class FormMain : Form {

public int newindex = 0;

public FormMain() { InitializeComponent(); }

private void makeNewMdiChild() { ImageBlaster9000.FormChild child = new ImageBlaster9000.FormChild(this); child.Show(); this.ActiveMdiChild.Text = "New-File-" + Convert.ToString(newindex); newindex += 1; }

private void newToolStripMenuItem_Click(object sender, EventArgs e) { makeNewMdiChild(); }

private void openImage() { int len; string fileName = ""; OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|Bitmap files (*.bmp)|*.bmp"; if (dlg.ShowDialog() == DialogResult.OK) { fileName = dlg.FileName; Bitmap img = new Bitmap(fileName); makeNewMdiChild(); FormChild activeChild = this.ActiveMdiChild as FormChild; len = fileName.Length; if (len > 40) activeChild.Text = fileName.Substring(0, 35) + "..." + fileName.Substring(len - 4, 4); else activeChild.Text = fileName; activeChild.loadImage(fileName); } } private void openToolStripMenuItem_Click(object sender, EventArgs e) { openImage(); }

private void grayscaleToolStripMenuItem_Click(object sender, EventArgs e) { FormChild activeChild = this.ActiveMdiChild as FormChild; if(activeChild != null) activeChild.grayscale(); }

private void grayscaleDemoToolStripMenuItem_Click(object sender, EventArgs e) { FormChild activeChild = this.ActiveMdiChild as FormChild; if(activeChild != null) activeChild.grayscaledemo(); } }}