lecture 8 building an mdi application. introduction the mdi (multiple document interface) provides a...
TRANSCRIPT
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 ...
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(); } }}