100 likes | 220 Views
Lecture 8 Building 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...
E N D
Lecture 8 Building 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 9000 A 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...
The Fast Image Processing Class - ImgPro 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 { publicstructPixelData { publicbyte blue; publicbyte green; publicbyte red; } publicunsafeclassImgPro { Bitmap bitmap; int width; BitmapData bitmapData = null; Byte* pBase = null; public ImgPro(Bitmap bitmap) { this.bitmap = bitmap; } publicvoid Save(string filename) { bitmap.Save(filename, ImageFormat.Jpeg); } publicvoid Dispose() { bitmap.Dispose(); } publicBitmap Bitmap { get { return (bitmap); } } 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. publicPoint PixelSize { get { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF bounds = bitmap.GetBounds(ref unit); returnnewPoint((int)bounds.Width, (int)bounds.Height); } } publicvoid 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(); }
LockBitmap( ), PixelAt( ), and UnlockBitmap( ) publicvoid LockBitmap() { GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF boundsF = bitmap.GetBounds(ref unit); Rectangle bounds = newRectangle((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(); } publicPixelData* PixelAt(int x, int y) { return (PixelData*)(pBase + y * width + x * sizeof(PixelData)); } publicvoid UnlockBitmap() { bitmap.UnlockBits(bitmapData); bitmapData = null; pBase = null; } } }
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
publicpartialclassFormMain : Form { publicint newindex = 0; public FormMain() { InitializeComponent(); } privatevoid makeNewMdiChild() { ImageBlaster9000.FormChild child = new ImageBlaster9000.FormChild(this); child.Show(); this.ActiveMdiChild.Text = "New-File-" + Convert.ToString(newindex); newindex += 1; } privatevoid newToolStripMenuItem_Click(object sender, EventArgs e) { makeNewMdiChild(); } privatevoid openImage() { intlen; string fileName = ""; OpenFileDialog dlg = newOpenFileDialog(); dlg.Filter = "JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|Bitmap files (*.bmp)|*.bmp"; if (dlg.ShowDialog() == DialogResult.OK) { fileName = dlg.FileName; Bitmap img = newBitmap(fileName); makeNewMdiChild(); FormChild activeChild = this.ActiveMdiChild asFormChild; len = fileName.Length; if (len > 40) activeChild.Text = fileName.Substring(0, 35) + "..." + fileName.Substring(len - 4, 4); else activeChild.Text = fileName; activeChild.loadImage(fileName); } } privatevoid openToolStripMenuItem_Click(object sender, EventArgs e) { openImage(); }
privatevoid grayscaleToolStripMenuItem_Click(object sender, EventArgs e) { FormChild activeChild = this.ActiveMdiChild asFormChild; if(activeChild != null) activeChild.grayscale(); } privatevoid grayscaleDemoToolStripMenuItem_Click(object sender, EventArgs e) { FormChild activeChild = this.ActiveMdiChild asFormChild; if(activeChild != null) activeChild.grayscaledemo(); } } }