Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сохранить файл jpg не меняя его размер? Стеганография изображений 
:(
    Опции темы
vinograd2008
Дата 7.12.2011, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.12.2008

Репутация: нет
Всего: нет



Здравствуйте. Пишу программу для стеганографии изображений. На входе есть 2 графических файла формат jpg размером 35,0 Кб оригинальное и модифицированное изображение формата jpg отрываю их с помощью программы они оба загружаются нормально сохраняю модифицированное изображение в формат .jpg и файл теперь весит 34,9 Кб т.е. размер файла меняется уменьшается куда девается 1 байт никак не пойму может дело в качестве изображения. Как сохранить модифицированное изображение файл формата .jpg не меняя его физического размера и не теряя качества изображения?

Код


 public partial class Steganography : Form
    {
        PasswordForm passwordForm = new PasswordForm();
        Bitmap bmpOriginal;
        Bitmap bmpModified;
        byte[] exampleFile;
        byte[] exFile;
        byte[] file;

        public Steganography()
        {
            InitializeComponent();
        }

        private void SteganographyAlgorithmForm_Paint(object sender, PaintEventArgs e)
        {
            OriginalPictureBox.Image = bmpOriginal;
            if (bmpModified == null)
            {
                return;
            }

            ModifiedPictureBox.Image = bmpModified;
        }

        private byte[] PasswordSHA(string password)
        {
            return new SHA256Managed().ComputeHash(Encoding.ASCII.GetBytes(password));
        }

        private byte[] EncryptionSymmetricAlgorithm(byte[] file, byte[] password, SymmetricAlgorithm sa, CipherMode cm, PaddingMode pm)
        {
            byte[] buffer;
            byte[] cipherbytes;

            sa.Key = password;
            sa.IV = new byte[] { 2, 3, 1, 86, 31, 76, 24, 46, 31, 76, 24, 46, 86, 31, 76, 24 };

            sa.Mode = cm;
            sa.Padding = pm;

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(
                ms,
                sa.CreateEncryptor(),
                CryptoStreamMode.Write);

            buffer = file;
            cs.Write(buffer, 0, buffer.Length);
            cs.Close();

            cipherbytes = ms.ToArray();
            ms.Close();
            return cipherbytes;
        }

        private void SaveAImage(byte[] file)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;

                bmpModified = new Bitmap(bmpOriginal, bmpOriginal.Width, bmpOriginal.Height);

                int numberbytes = file.Length;
                byte[] bytesOriginal = new byte[numberbytes + 1];
                bytesOriginal[0] = (byte)numberbytes;

                for (int i = 0; i < file.Length; i++)
                {
                    bytesOriginal[i + 1] = file[i];
                }

                int byteCount = 0;

                for (int i = 0; i < bmpOriginal.Width; i++)
                {
                    for (int j = 0; j < bmpOriginal.Height; j++)
                    {
                        if (bytesOriginal.Length == byteCount)
                            return;

                        Color clrPixelOriginal = bmpOriginal.GetPixel(i, j);
                        byte r = (byte)((clrPixelOriginal.R & ~0x7) | (bytesOriginal[byteCount] >> 0) & 0x7);
                        byte g = (byte)((clrPixelOriginal.G & ~0x7) | (bytesOriginal[byteCount] >> 3) & 0x7);
                        byte b = (byte)((clrPixelOriginal.B & ~0x3) | (bytesOriginal[byteCount] >> 6) & 0x3);
                        byteCount++;

                        bmpModified.SetPixel(i, j, Color.FromArgb(r, g, b));
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error hiding message." + ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Arrow;

                Invalidate();
            }
        }

        private void ExtractTheFile()
        {
            byte[] bytesExtracted = new byte[256 + 1];
            try
            {
                this.Cursor = Cursors.WaitCursor;

                int byteCount = 0;

                for (int i = 0; i < bmpModified.Width; i++)
                {
                    for (int j = 0; j < bmpModified.Height; j++)
                    {
                        if (bytesExtracted.Length == byteCount)
                        {
                            return;
                        }

                        Color clrPixelModified = bmpModified.GetPixel(i, j);
                        byte bits123 = (byte)((clrPixelModified.R & 0x7) << 0);
                        byte bits456 = (byte)((clrPixelModified.G & 0x7) << 3);
                        byte bits78 = (byte)((clrPixelModified.B & 0x3) << 6);

                        bytesExtracted[byteCount] = (byte)(bits78 | bits456 | bits123);
                        byteCount++;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error extracting message." + ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Arrow;

                int numberbytes = bytesExtracted[0];

                byte[] file = new byte[numberbytes];
                for (int i = 0; i < numberbytes; i++)
                {
                    file[i] = bytesExtracted[i + 1];
                }
                exFile = file;
            }
        }

        private byte[] DecryptionSymmetricAlgorithm(byte[] cipherbytes, byte[] password, SymmetricAlgorithm sa, CipherMode cm, PaddingMode pm)
        {
            byte[] buffer;

            sa.Key = password;
            sa.IV = new byte[] { 2, 3, 1, 86, 31, 76, 24, 46, 31, 76, 24, 46, 86, 31, 76, 24 };

            sa.Mode = cm;
            sa.Padding = pm;

            MemoryStream ms = new MemoryStream(cipherbytes);
            CryptoStream cs = new CryptoStream(
                ms,
                sa.CreateDecryptor(),
                CryptoStreamMode.Read);

            buffer = new Byte[cipherbytes.Length];
            cs.Read(buffer, 0, cipherbytes.Length);
            cs.Close();
            ms.Close();

            return buffer;
        }

        private void openFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
                exampleFile = File.ReadAllBytes(openFileDialog.FileName);
        }

        private void originalImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                bmpOriginal = (Bitmap)Bitmap.FromFile(openFileDialog.FileName);
            }
        }

        private void modifiedImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                bmpOriginal = (Bitmap)Bitmap.FromFile(openFileDialog.FileName);
                bmpModified = (Bitmap)Bitmap.FromFile(openFileDialog.FileName);
            }
        }

        private void saveFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (passwordForm.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            ExtractTheFile();

            try
            {
                file = DecryptionSymmetricAlgorithm(
                   exFile,
                   PasswordSHA(passwordForm.Password),
                   Rijndael.Create(),
                   CipherMode.ECB,
                   PaddingMode.Zeros
                   );

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    File.WriteAllText(saveFileDialog.FileName, Encoding.GetEncoding(1251).GetString(file));
                }

                
            }
            catch (Exception ex)
            {
                MessageBox.Show("Wrong password. " + ex);
            }
        }

        private void modifiedIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (passwordForm.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            SaveAImage(EncryptionSymmetricAlgorithm(
                exampleFile,
                PasswordSHA(passwordForm.Password),
                Rijndael.Create(),
                CipherMode.ECB,
                PaddingMode.Zeros
                ));

            saveFileDialog.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*";

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                long quality = 90L;

                if (quality < 0 || quality > 100)
                {
                    throw new ArgumentOutOfRangeException("quality must be between 0 and 100");
                }

                EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

                EncoderParameters encoderParameters = new EncoderParameters(1);
                encoderParameters.Param[0] = qualityParam;
                ModifiedPictureBox.Image.Save(saveFileDialog.FileName, GetEncoder(ImageFormat.Jpeg), encoderParameters);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        public static ImageCodecInfo GetEncoder(ImageFormat format)
        {
           ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

           foreach (ImageCodecInfo codec in codecs)
           {
               if (codec.FormatID == format.Guid)
               {
                   return codec;
               }
           }

           return null;
       }

   public partial class PasswordForm : Form
    {
         public string Password { get; set; }

        public PasswordForm()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, EventArgs e)
        {
            Password = PasswordTextBox.Text;
            Close();
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            Password = "";
            Close();
        }
    }

PM MAIL   Вверх
GhosTer
Дата 16.12.2011, 07:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.5.2007

Репутация: нет
Всего: нет



Меняя хоть один пиксел, ты без вариантно меняешь его размер. Этого не избежать... Ибо 0 и 1 это разные вещи.

Ибо красный пиксел это, к примеру, 101, а вот его оттенок может быть, к примеру, 10101101.

Как ни крути, а на один бит веса информация меняется.

Но ты можешь убрать оттенки и использовать только цвета радуги) Но и качество изображения, естественно, уже изменится. Только учти что и двоичный код красного кардинально отличается от белого)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0785 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.