123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- // RGB2RGBA
- //===========
- // P. Poliakoff 2009
- //===================
- // allows to use a mask to define the alpha layer of a bitmap
- // Functionalities
- //==================
- /* V resizable window
- * V Load bitmap
- * V Load Mask
- * V Display bitmap
- * V Display Mask
- * V Display masked bitmap
- * V allow to disable partial opacity
- * V invert mask
- * V Allow to use same bitmap for loaded bitmap and mask
- * V allow to configure opacity threshold
- * V Save masked bitmap
- * V adapt the size of displayed images
- * V display About box
- * V ignore the alpha layer when already already present
- * V report error if mask and bitmap have not the same size
- * Possible imporvements:
- * ======================
- * allow to save the save mask as a grayscale bitmap
- * display images file names
- */
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Text;
- using System.Windows.Forms;
- namespace RGB2RGBA
- {
- public partial class Form1 : Form
- {
- Bitmap loadedImage;
- Bitmap originalMaskImage;
- Bitmap maskImage;
- Bitmap maskedImage;
- public Form1()
- {
- InitializeComponent();
- MessageBox.Show("Alpha Mask Editor 1.0: P. Poliakoff 2009" + Environment.NewLine + "This progam allows to add an Alpha layer to any bitmap", "About");
- }
- private Bitmap Create32bppImageAndClearAlpha(Bitmap tmpImage)
- {
- // declare the new image that will be returned by the function
- Bitmap returnedImage = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
-
- // create a graphics instance to draw the original image in the new one
- Rectangle rect = new Rectangle(0, 0, tmpImage.Width, tmpImage.Height);
- Graphics g = Graphics.FromImage(returnedImage);
- // create an image attribe to force a clearing of the alpha layer
- ImageAttributes imageAttributes=new ImageAttributes();
- float[][] colorMatrixElements = {
- new float[] {1,0,0,0,0},
- new float[] {0,1,0,0,0},
- new float[] {0,0,1,0,0},
- new float[] {0,0,0,0,0},
- new float[] {0,0,0,1,1}};
- ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
- imageAttributes.SetColorMatrix(colorMatrix,ColorMatrixFlag.Default,ColorAdjustType.Bitmap);
-
- // draw the original image
- g.DrawImage(tmpImage, rect, 0, 0, tmpImage.Width, tmpImage.Height,GraphicsUnit.Pixel,imageAttributes);
- g.Dispose();
- return returnedImage;
- }
- private void PrepareMaskedImage()
- {
- this.Cursor = Cursors.WaitCursor;
- if (this.loadedImage != null && this.maskImage != null)
- {
- if (this.loadedImage.Width != this.maskImage.Width || this.loadedImage.Height != this.maskImage.Height)
- {
- MessageBox.Show("Error: mask and image must have the same size", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
- this.pictureBox3.Image = null;
-
- }
- else
- {
- //allocate the Masked image in ARGB format
- this.maskedImage = Create32bppImageAndClearAlpha(this.loadedImage);
- BitmapData bmpData1 = maskedImage.LockBits(new Rectangle(0, 0, maskedImage.Width, maskedImage.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, maskedImage.PixelFormat);
- byte[] maskedImageRGBAData = new byte[bmpData1.Stride * bmpData1.Height];
- System.Runtime.InteropServices.Marshal.Copy(bmpData1.Scan0, maskedImageRGBAData, 0, maskedImageRGBAData.Length);
- BitmapData bmpData2 = maskImage.LockBits(new Rectangle(0, 0, maskImage.Width, maskImage.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, maskImage.PixelFormat);
- byte[] maskImageRGBAData = new byte[bmpData2.Stride * bmpData2.Height];
- System.Runtime.InteropServices.Marshal.Copy(bmpData2.Scan0, maskImageRGBAData, 0, maskImageRGBAData.Length);
- //copy the mask to the Alpha layer
- for (int i = 0; i + 2 < maskedImageRGBAData.Length; i += 4)
- {
- maskedImageRGBAData[i + 3] = maskImageRGBAData[i];
- }
- System.Runtime.InteropServices.Marshal.Copy(maskedImageRGBAData, 0, bmpData1.Scan0, maskedImageRGBAData.Length);
- this.maskedImage.UnlockBits(bmpData1);
- this.maskImage.UnlockBits(bmpData2);
- this.pictureBox3.Image = maskedImage;
- }
- this.Cursor = Cursors.Default;
- }
- }
- private void PrepareMaskImage()
- {
- if (originalMaskImage != null)
- {
- this.Cursor = Cursors.WaitCursor;
- this.maskImage = Create32bppImageAndClearAlpha(originalMaskImage);
- BitmapData bmpData = maskImage.LockBits(new Rectangle(0, 0, maskImage.Width, maskImage.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, maskImage.PixelFormat);
- byte[] maskImageRGBData = new byte[bmpData.Stride * bmpData.Height];
- System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, maskImageRGBData, 0, maskImageRGBData.Length);
- byte greyLevel;
- bool opaque = this.checkBoxAllowPartialOpacity.Checked == false;
- int OpacityThreshold = this.trackBar1.Value;
- bool invertedMask = this.checkBoxInvertMask.Checked;
- for (int i = 0; i + 2 < maskImageRGBData.Length; i += 4)
- {
- //convert to gray scale R:0.30 G=0.59 B 0.11
- greyLevel = (byte)(0.3 * maskImageRGBData[i + 2] + 0.59 * maskImageRGBData[i + 1] + 0.11 * maskImageRGBData[i]);
- if (opaque)
- {
- greyLevel = (greyLevel < OpacityThreshold) ? byte.MinValue : byte.MaxValue;
- }
- if (invertedMask)
- {
- greyLevel = (byte)(255 - (int)greyLevel);
- }
- maskImageRGBData[i] = greyLevel;
- maskImageRGBData[i + 1] = greyLevel;
- maskImageRGBData[i + 2] = greyLevel;
- }
- System.Runtime.InteropServices.Marshal.Copy(maskImageRGBData, 0, bmpData.Scan0, maskImageRGBData.Length);
- this.maskImage.UnlockBits(bmpData);
- this.pictureBox2.Image = maskImage;
- this.Cursor = Cursors.Default;
- // if the loaded image is available, we have everything to compute the masked image
- if (this.loadedImage != null)
- {
- PrepareMaskedImage();
- }
- }
- }
- private void buttonLoadImage_Click(object sender, EventArgs e)
- {
- if (openFileDialog1.ShowDialog() == DialogResult.OK)
- {
- loadedImage = Create32bppImageAndClearAlpha(new Bitmap(openFileDialog1.FileName));
- pictureBox1.Image = loadedImage;
- if (this.checkBoxLoadedImageAsMask.Checked)
- {
- originalMaskImage = (Bitmap)loadedImage.Clone();
- PrepareMaskImage();
- }
- else if (this.maskImage != null)
- {
- PrepareMaskedImage();
- }
- }
- }
- private void buttonLoadMask_Click(object sender, EventArgs e)
- {
- if (openFileDialog1.ShowDialog() == DialogResult.OK)
- {
- originalMaskImage = Create32bppImageAndClearAlpha(new Bitmap(openFileDialog1.FileName));
- PrepareMaskImage();
- }
- }
- private void checkBoxUseLoadedImageAsMask_CheckedChanged(object sender, EventArgs e)
- {
- if (this.checkBoxLoadedImageAsMask.Checked)
- {
- this.buttonLoadMask.Enabled = false;
- if (this.loadedImage != null)
- {
- originalMaskImage = (Bitmap)this.loadedImage.Clone();
- PrepareMaskImage();
- }
- }
- else
- {
- this.buttonLoadMask.Enabled = true;
- }
- }
- private void checkBoxInvertMask_CheckedChanged(object sender, EventArgs e)
- {
- PrepareMaskImage();
- }
- private void checkBoxPartialOpacity_CheckedChanged(object sender, EventArgs e)
- {
- if (this.checkBoxAllowPartialOpacity.Checked)
- {
- this.trackBar1.Enabled = false;
- this.textBoxOpacityThreshold.Enabled = false;
- }
- else
- {
- this.trackBar1.Enabled = true;
- this.textBoxOpacityThreshold.Enabled = true;
- }
- PrepareMaskImage();
- }
- private void trackBar1_ValueChanged(object sender, EventArgs e)
- {
- PrepareMaskImage();
- }
- private void ButtonSave_Click(object sender, EventArgs e)
- {
- if (maskedImage != null && this.saveFileDialog1.ShowDialog() == DialogResult.OK)
- {
- maskedImage.Save(this.saveFileDialog1.FileName);
- }
- }
- private void buttonSaveMask_Click(object sender, EventArgs e)
- {
- if (maskImage != null && this.saveFileDialog1.ShowDialog() == DialogResult.OK)
- {
- maskImage.Save(this.saveFileDialog1.FileName);
- }
- }
- }
- }
|