/// <summary> /// Embeds content in the image /// </summary> /// <param name="imageFile">the image file in which to embed</param> /// <param name="planes">the planes to embed in</param> /// <param name="bitDepth">the bit depth of the embedding</param> /// <param name="content">the content to embed</param> /// <returns>the image with the data embedded if successful, otherwise null</returns> public static Bitmap Embed(String imageFile, EmbeddingPlane planes, int bitDepth, EmbeddingContent content) { // var init Bitmap retVal = null; // wrap call try { retVal = new Bitmap(imageFile); if (SteganographyMethods.Embed(retVal, planes, bitDepth, content) == false) { throw new SteganographyException(String.Empty); } } catch { if (retVal != null) { retVal.Dispose(); } retVal = null; } return(retVal); }
/// <summary> /// Extracts the content from the image /// </summary> /// <param name="img">the image from which to extract</param> /// <param name="planes">the planes to embed in</param> /// <param name="bitDepth">the bit depth of the embedding</param> /// <returns>the embedded content, null if a problem occurs</returns> public static EmbeddingContent Extract(Bitmap img, EmbeddingPlane planes, int bitDepth) { // short circuit if ((img == null) || (bitDepth < 1) || (bitDepth > 8)) { return(null); } // var declatation EmbeddingContent retVal = null; try { // get the header to determine what to extract EmbeddingHeader eh = new EmbeddingHeader(img, planes, bitDepth); // read the bytes int totalBytesToExtract = eh.ToString().Length + eh.SizeOfContent; retVal = new EmbeddingContent(SteganographyMethods.ExtractBytes(img, planes, bitDepth, totalBytesToExtract)); } catch { retVal = null; } return(retVal); }
/// <summary> /// Embed content /// </summary> /// <param name="sender">caused the event</param> /// <param name="e">event params</param> private void embedButton_Click(object sender, EventArgs e) { // var init Boolean success = false; // show an error if nothing to embed if (this.destFile.Text.Trim() == String.Empty) { MessageBox.Show("You must supply a destination file in which to embed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if ((ContentType)Enum.Parse(typeof(ContentType), this.embedContentType.SelectedItem.ToString()) == ContentType.Text) { if (this.embedText.Text.Trim() == String.Empty) { MessageBox.Show("You must supply text to embed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { EmbeddingContent content = new EmbeddingContent(this.embedText.Text); EmbeddingPlane planes = (EmbeddingPlane)Enum.Parse(typeof(EmbeddingPlane), this.embedPlane.SelectedItem.ToString()); byte bitDepth = Convert.ToByte(this.embedBitDepth.SelectedItem.ToString()); using (Bitmap img = SteganographyMethods.Embed(this.sourceFile.Text.Trim(), planes, bitDepth, content)) { ImageFormat format = (this.destFileType.SelectedItem.ToString() == "Bmp") ? ImageFormat.Bmp : ImageFormat.Png; success = MainWindow.SaveImgToFile(img, this.destFile.Text.Trim(), format); } } } else if ((ContentType)Enum.Parse(typeof(ContentType), this.embedContentType.SelectedItem.ToString()) == ContentType.File) { if (this.embedFile.Text.Trim() == String.Empty) { MessageBox.Show("You must supply a file to embed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { EmbeddingContent content = new EmbeddingContent(new FileInfo(this.embedFile.Text.Trim())); EmbeddingPlane planes = (EmbeddingPlane)Enum.Parse(typeof(EmbeddingPlane), this.embedPlane.SelectedItem.ToString()); byte bitDepth = Convert.ToByte(this.embedBitDepth.SelectedItem.ToString()); using (Bitmap img = SteganographyMethods.Embed(this.sourceFile.Text.Trim(), planes, bitDepth, content)) { ImageFormat format = (this.destFileType.SelectedItem.ToString() == "Bmp") ? ImageFormat.Bmp : ImageFormat.Png; success = MainWindow.SaveImgToFile(img, this.destFile.Text.Trim(), format); } } } // notify if the operation is successful if (success == true) { MessageBox.Show("The operation was completed", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// Updates the bytes available on the embed tab /// </summary> private void UpdateBytesAvailable() { // try to figure out how many bytes are available in the file try { using (Bitmap img = new Bitmap(this.sourceFile.Text)) { int bitDepth = Convert.ToInt32(this.embedBitDepth.SelectedItem.ToString()); EmbeddingPlane planes = (EmbeddingPlane)Enum.Parse(typeof(EmbeddingPlane), this.embedPlane.SelectedItem.ToString()); this.bytesInPicture.Text = SteganographyMethods.MaxBytesInImage(img, planes, bitDepth).ToString(); } } catch { this.bytesInPicture.Text = "N/A"; } }
/// <summary> /// Calculates the maximum number of bytes which can be stored /// </summary> /// <param name="img">the image to determine the max amount of bytes whithin</param> /// <param name="planes">which planes to embed in</param> /// <param name="bitDepth">the number of bits to embed [1, 8]</param> /// <returns>the number of bytes, 0 on error</returns> public static int MaxBytesInImage(Bitmap img, EmbeddingPlane planes, int bitDepth) { // short circuit if ((img == null) || (bitDepth < 1) || (bitDepth > 8)) { return(0); } // calculate the maximum number of bytes int bitsAvailable = img.Height * img.Width * bitDepth; int bytesAvailable = Convert.ToInt32(Math.Floor(bitsAvailable / 8.0)); if (planes == EmbeddingPlane.RGB) { bytesAvailable = bytesAvailable * 3; } return(bytesAvailable); }
/// Extracts the content from the image /// </summary> /// <param name="imageFile">the image file from which to extract</param> /// <param name="planes">the planes to embed in</param> /// <param name="bitDepth">the bit depth of the embedding</param> /// <returns>the embedded content, null if a problem occurs</returns> public static EmbeddingContent Extract(String imageFile, EmbeddingPlane planes, int bitDepth) { // var init EmbeddingContent retVal = null; // wrap call try { using (Bitmap img = new Bitmap(imageFile)) { retVal = SteganographyMethods.Extract(img, planes, bitDepth); } } catch { retVal = null; } return(retVal);; }
/// <summary> /// Internal constructor that builds the object from bytes /// </summary> /// <param name="img">the image in which to embed</param> /// <param name="planes">the planes to embed in</param> /// <param name="bitDepth">the bit depth of the embedding</param> /// <returns>the embedding header</returns> internal EmbeddingHeader(Bitmap img, EmbeddingPlane planes, int bitDepth) { try { // get header byte[] headerBytes = SteganographyMethods.ExtractBytes(img, planes, bitDepth, MAX_HEADER); String header = System.Text.Encoding.ASCII.GetString(headerBytes).Trim(); String[] split = header.Split(new char[1] { HEADER_SPLIT_CHAR }); // set attributes this.TypeOfContent = (ContentType)Enum.Parse(typeof(ContentType), split[0].Trim()); this.SizeOfContent = Convert.ToInt32(split[1].Trim()); this.Filename = split[2].Trim(); } catch (Exception e) { throw new SteganographyException(e.ToString()); } }
/// <summary> /// Extract content /// </summary> /// <param name="sender">caused the event</param> /// <param name="e">event params</param> private void extractButton_Click(object sender, EventArgs e) { // clear the extracted text box this.extractedText.Text = String.Empty; // extract! EmbeddingPlane planes = (EmbeddingPlane)Enum.Parse(typeof(EmbeddingPlane), this.extractPlane.SelectedItem.ToString()); byte bitDepth = Convert.ToByte(this.extractBitDepth.SelectedItem.ToString()); EmbeddingContent content = SteganographyMethods.Extract(this.sourceFile.Text.Trim(), planes, bitDepth); if (content == null) { // nothing was extracted, show an error message box MessageBox.Show("An error occurred while extracting", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { if (content.Header.TypeOfContent == ContentType.Text) { // text was extracted, put in extracted text box this.extractedText.Text = Encoding.ASCII.GetString(content.Content); } else { // write to file String newFilename = String.Format("extracted_{0}", content.Header.Filename); String newPathAndFilename = Path.Combine(Path.GetDirectoryName(this.sourceFile.Text), newFilename); File.WriteAllBytes(newPathAndFilename, content.Content); // extraction mesage String extractionMessage = String.Format("Successfully extracted file: {0}", newFilename); // notify that a file was extracted this.extractedText.Text = extractionMessage; MessageBox.Show(extractionMessage, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } } }
/// <summary> /// Get bytes hidden in a picture's plane /// </summary> /// <param name="img">the picture to extract data from</param> /// <param name="planes">what pleanes to extract from</param> /// <param name="bitDepth">the bit depth to extract [1, 8]</param> /// <param name="bytesToGet">the number of bytes to retrieve</param> /// <returns>a byte array of data, null if there is a problem</returns> internal static byte[] ExtractBytes(Bitmap img, EmbeddingPlane planes, int bitDepth, int bytesToGet) { // var declatation byte[] retVal = new Byte[bytesToGet]; int currentByteIndex = 0; byte currentBitIndex = 1; try { // loop through the x and y pixels of the image, as well as the correct bit depths for (int x = 0; x < img.Width; x++) { for (int y = 0; y < img.Height; y++) { for (byte extractBit = 1; extractBit <= bitDepth; extractBit++) { // extract from R if ((planes == EmbeddingPlane.R) || (planes == EmbeddingPlane.RGB)) { Color rgb = img.GetPixel(x, y); byte r = SteganographyMethods.GetBitValueFromByte(rgb.R, extractBit); retVal[currentByteIndex] = SteganographyMethods.SetBitValueInByte(retVal[currentByteIndex], currentBitIndex, r); // enumerate bit/byte counter currentBitIndex++; if (currentBitIndex > 8) { currentBitIndex = 1; currentByteIndex++; } if (currentByteIndex >= bytesToGet) { x = img.Width; y = img.Height; break; } } // extract from G if ((planes == EmbeddingPlane.G) || (planes == EmbeddingPlane.RGB)) { Color rgb = img.GetPixel(x, y); byte g = SteganographyMethods.GetBitValueFromByte(rgb.G, extractBit); retVal[currentByteIndex] = SteganographyMethods.SetBitValueInByte(retVal[currentByteIndex], currentBitIndex, g); // enumerate bit/byte counter currentBitIndex++; if (currentBitIndex > 8) { currentBitIndex = 1; currentByteIndex++; } if (currentByteIndex >= bytesToGet) { x = img.Width; y = img.Height; break; } } // extract from B if ((planes == EmbeddingPlane.B) || (planes == EmbeddingPlane.RGB)) { Color rgb = img.GetPixel(x, y); byte b = SteganographyMethods.GetBitValueFromByte(rgb.B, extractBit); retVal[currentByteIndex] = SteganographyMethods.SetBitValueInByte(retVal[currentByteIndex], currentBitIndex, b); // enumerate bit/byte counter currentBitIndex++; if (currentBitIndex > 8) { currentBitIndex = 1; currentByteIndex++; } if (currentByteIndex >= bytesToGet) { x = img.Width; y = img.Height; break; } } } } } } catch (Exception) { retVal = null; } return(retVal); }
/// <summary> /// Embeds content in the image /// </summary> /// <param name="img">the image in which to embed</param> /// <param name="planes">the planes to embed in</param> /// <param name="bitDepth">the bit depth of the embedding</param> /// <param name="content">the content to embed</param> /// <returns>true if successful</returns> public static Boolean Embed(Bitmap img, EmbeddingPlane planes, int bitDepth, EmbeddingContent content) { // short circuit if ((img == null) || (bitDepth < 1) || (bitDepth > 8) || (content == null) || (content.HeaderAndContent.Length > SteganographyMethods.MaxBytesInImage(img, planes, bitDepth))) { return(false); } // var init Boolean retVal = true; int currentByteIndex = 0; byte currentBitIndex = 1; try { // loop through the x and y pixels of the image, as well as the correct bit depths for (int x = 0; x < img.Width; x++) { for (int y = 0; y < img.Height; y++) { for (byte embedBit = 1; embedBit <= bitDepth; embedBit++) { // embed in R if ((planes == EmbeddingPlane.R) || (planes == EmbeddingPlane.RGB)) { Color rgb = img.GetPixel(x, y); byte r = SteganographyMethods.SetBitValueInByte(rgb.R, embedBit, SteganographyMethods.GetBitValueFromByte(content.HeaderAndContent[currentByteIndex], currentBitIndex)); img.SetPixel(x, y, Color.FromArgb(r, rgb.G, rgb.B)); // enumerate bit/byte counter currentBitIndex++; if (currentBitIndex > 8) { currentBitIndex = 1; currentByteIndex++; } if (currentByteIndex >= content.HeaderAndContent.Length) { x = img.Width; y = img.Height; break; } } // embed in G if ((planes == EmbeddingPlane.G) || (planes == EmbeddingPlane.RGB)) { Color rgb = img.GetPixel(x, y); byte g = SteganographyMethods.SetBitValueInByte(rgb.G, embedBit, SteganographyMethods.GetBitValueFromByte(content.HeaderAndContent[currentByteIndex], currentBitIndex)); img.SetPixel(x, y, Color.FromArgb(rgb.R, g, rgb.B)); // enumerate bit/byte counter currentBitIndex++; if (currentBitIndex > 8) { currentBitIndex = 1; currentByteIndex++; } if (currentByteIndex >= content.HeaderAndContent.Length) { x = img.Width; y = img.Height; break; } } // embed in B if ((planes == EmbeddingPlane.B) || (planes == EmbeddingPlane.RGB)) { Color rgb = img.GetPixel(x, y); byte b = SteganographyMethods.SetBitValueInByte(rgb.B, embedBit, SteganographyMethods.GetBitValueFromByte(content.HeaderAndContent[currentByteIndex], currentBitIndex)); img.SetPixel(x, y, Color.FromArgb(rgb.R, rgb.G, b)); // enumerate bit/byte counter currentBitIndex++; if (currentBitIndex > 8) { currentBitIndex = 1; currentByteIndex++; } if (currentByteIndex >= content.HeaderAndContent.Length) { x = img.Width; y = img.Height; break; } } } } } } catch { retVal = false; } return(retVal); }