// ------------------------------------------ // PaletteChange.cs (c) Charles Petzold, 2003 // // Converts Bitmap to Monochrome // ----------------------------------------- using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Windows.Forms; class PaletteChange: Form { MenuItem miFile, miSave; string strProgName = "Palette Change"; string strFileName; Bitmap bmMono; static void Main() { Application.Run(new PaletteChange()); } public PaletteChange() { Text = strProgName; ResizeRedraw = true; // Assemble "File" menu Menu = new MainMenu(); miFile = new MenuItem("&File"); Menu.MenuItems.Add(miFile); MenuItem mi = new MenuItem("&Open..."); mi.Click += new EventHandler(MenuFileOpenOnClick); mi.Shortcut = Shortcut.CtrlO; miFile.MenuItems.Add(mi); miSave = new MenuItem("&Save..."); miSave.Click += new EventHandler(MenuFileSaveOnClick); miSave.Shortcut = Shortcut.CtrlS; miFile.MenuItems.Add(miSave); } void MenuFileOnPopup(object obj, EventArgs ea) { miSave.Enabled = (bmMono != null); } void MenuFileOpenOnClick(object obj, EventArgs ea) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "All Image Files|*.bmp;*.ico;*.gif;*.jpeg;*.jpg;" + "*.jfif;*.png;*.tif;*.tiff;*.wmf;*.emf|" + "Windows Bitmap (*.bmp)|*.bmp|" + "Windows Icon (*.ico)|*.ico|" + "Graphics Interchange Format (*.gif)|*.gif|" + "JPEG File Interchange Format (*.jpg)|*.jpg;*.jpeg;*.jfif|" + "Portable Network Graphics (*.png)|*.png|" + "Tag Image File Format (*.tif)|*.tif;*.tiff|" + "All Files (*.*)|*.*"; if (dlg.ShowDialog() == DialogResult.OK) { try { Bitmap bm = new Bitmap(dlg.FileName); bmMono = ConvertToMonochrome(bm); } catch (Exception exc) { MessageBox.Show(exc.Message, strProgName); return; } strFileName = dlg.FileName; Text = strProgName + " - " + Path.GetFileName(strFileName); Invalidate(); } } void MenuFileSaveOnClick(object obj, EventArgs ea) { SaveFileDialog savedlg = new SaveFileDialog(); savedlg.InitialDirectory = Path.GetDirectoryName(strFileName); savedlg.FileName = Path.GetFileNameWithoutExtension(strFileName); savedlg.AddExtension = true; savedlg.Filter = "Windows Bitmap (*.bmp)|*.bmp|" + "Graphics Interchange Format (*.gif)|*.gif|" + "JPEG File Interchange Format (*.jpg)|" + "*.jpg;*.jpeg;*.jfif|" + "Portable Network Graphics (*.png)|*.png|" + "Tagged Imaged File Format (*.tif)|*.tif;*.tiff"; ImageFormat[] aif = { ImageFormat.Bmp, ImageFormat.Gif, ImageFormat.Jpeg, ImageFormat.Png, ImageFormat.Tiff }; if (savedlg.ShowDialog() == DialogResult.OK) { try { bmMono.Save(savedlg.FileName, aif[savedlg.FilterIndex - 1]); } catch (Exception exc) { MessageBox.Show(exc.Message, Text); return; } strFileName = savedlg.FileName; Text = strProgName + " - " + Path.GetFileName(strFileName); } } protected override void OnPaint(PaintEventArgs pea) { Graphics grfx = pea.Graphics; if (bmMono != null) grfx.DrawImage(bmMono, 0, 0); } static unsafe Bitmap ConvertToMonochrome(Bitmap bmColor) { int cx = bmColor.Width; int cy = bmColor.Height; // Create a new 8-bit indexed bitmap of the same size Bitmap bmMono = new Bitmap(cx, cy, PixelFormat.Format8bppIndexed); bmMono.SetResolution(bmColor.HorizontalResolution, bmColor.VerticalResolution); // Set the palette for gray shades ColorPalette pal = bmMono.Palette; for (int i = 0; i < pal.Entries.Length; i++) pal.Entries[i] = Color.FromArgb(i, i, i); bmMono.Palette = pal; // Because SetPixel won't work with index bitmaps, we need // direct access to the bits BitmapData bmd = bmMono.LockBits( new Rectangle(Point.Empty, bmMono.Size), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // Scan through the pixels, converting color to B&W Byte * pPixel = (Byte *) bmd.Scan0; for (int y = 0; y < cy; y++) { for (int x = 0; x < cx; x++) { Color clr = bmColor.GetPixel(x, y); Byte byPixel = (byte) ((30 * clr.R + 59 * clr.G + 11 * clr.B) / 100); pPixel[x] = byPixel; } pPixel += bmd.Stride; } bmMono.UnlockBits(bmd); return bmMono; } }