Пример #1
0
        private const int SizeSegment = 8; // размер сегмента

        // функция сокрытия текста в изображении
        public static StegoBitmap Hide(StegoBitmap stgbmap, string txt, Colours colour, int CoefDif)
        {
            var bmap = stgbmap.GetImage();

            if ((bmap.Width % SizeSegment) != 0 || (bmap.Height % SizeSegment) != 0) //если изображение не делится на сегменты ровно
            {
                CommonFunc.Cut(ref bmap, SizeSegment);
            }

            var arrForHiding = new byte[bmap.Width, bmap.Height]; // массив байтов, где будет хранится текст в соотвествии с выбранным цветом

            //выбираем из изображения пиксели в соответствии с переданным цветом
            for (int i = 0; i < bmap.Width; i++)
            {
                for (int j = 0; j < bmap.Height; j++)
                {
                    if (colour == Colours.Red)
                    {
                        arrForHiding[i, j] = bmap.GetPixel(i, j).R;
                    }
                    else if (colour == Colours.Green)
                    {
                        arrForHiding[i, j] = bmap.GetPixel(i, j).G;
                    }
                    else if (colour == Colours.Blue)
                    {
                        arrForHiding[i, j] = bmap.GetPixel(i, j).B;
                    }
                    else
                    {
                        throw new NullReferenceException();
                    }
                }
            }
            int numSegm = bmap.Width * bmap.Height / (SizeSegment * SizeSegment);            //общее число сегментов
            var stgByte = Encoding.GetEncoding(1251).GetBytes(txt);                          // перевод строки в массив байтов

            byte[] len     = CommonFunc.LenInBytes(txt.Length, CommonFunc.Size(txt.Length)); // массив байтов из длины текста в соответвии с размером его длины
            byte[] txtByte = new byte[2 + len.Length + stgByte.Length];                      //массив для скрытого текста размером в длину текста + размер длины + два дополнительных байта
            txtByte[0] = Convert.ToByte('Z');                                                // первый элемент массива содержит пометку, что в изображении скрыт текст
            txtByte[1] = CommonFunc.Size(txt.Length);                                        // второй элемент массива размер длины
            int ind = 0;

            for (int i = 0; i < len.Length; i++)
            {
                txtByte[i + 2] = len[ind++]; // сохраняем в массив байты из длины текста в соответвии с размером его длины
            }
            ind = 0;
            for (int i = 0; i < stgByte.Length; i++)
            {
                txtByte[i + 2 + len.Length] = stgByte[ind++]; // сохраняем в массив скрываемый текст
            }
            var segm = new List <byte[, ]>();

            Separate(arrForHiding, segm, bmap.Width, bmap.Height, SizeSegment);// разбиваем массив на сегменты
            // дискретное косинусное преобразование
            var dctList = new List <double[, ]>();

            foreach (var b in segm)
            {
                dctList.Add(DCT(b));                // список из коэффициентов ДКП
            }
            SetText(txtByte, ref dctList, CoefDif); // внедрение текста
            // обратное дискретное косинусное преобразование
            var idctList = new List <double[, ]>();

            foreach (var d in dctList)
            {
                idctList.Add(IDCT(d));
            }
            var newArr = new double[bmap.Width, bmap.Height];                 // новый массив значений

            Join(ref newArr, idctList, bmap.Width, bmap.Height, SizeSegment); //соединяем сегменты
            Normalize(ref newArr);                                            // модификация коэффициентов ДКП иногда приводит к выходу значений интенсивностей пикселей изображения за пределы допустимого диапазона [0,255], проводим нормирование указанных значений
            return(new StegoBitmap(bmap, newArr, colour));
        }
Пример #2
0
        // функция находит скрытый текст
        public static string GetHiddenText(StegoBitmap stgbmap, Colours c)
        {
            var bmap         = stgbmap.GetImage();
            int width        = bmap.Width;
            int height       = bmap.Height;
            var arrWhereHide = new byte[bmap.Width, bmap.Height]; // массив байтов, где будет хранится текст в соотвествии с выбранным цветом

            //выбираем из изображения пиксели в соответствии с переданным цветом
            for (int i = 0; i < bmap.Width; i++)
            {
                for (int j = 0; j < bmap.Height; j++)
                {
                    if (c == Colours.Red)
                    {
                        arrWhereHide[i, j] = bmap.GetPixel(i, j).R;
                    }
                    else if (c == Colours.Green)
                    {
                        arrWhereHide[i, j] = bmap.GetPixel(i, j).G;
                    }
                    else if (c == Colours.Blue)
                    {
                        arrWhereHide[i, j] = bmap.GetPixel(i, j).B;
                    }
                    else
                    {
                        throw new NullReferenceException();
                    }
                }
            }
            int numSegm = bmap.Width * bmap.Height / (SizeSegment * SizeSegment); //общее число сегментов
            var segm    = new List <byte[, ]>();

            Separate(arrWhereHide, segm, bmap.Width, bmap.Height, SizeSegment);// разбиваем массив на сегменты
            // дискретное косинусное преобразование
            var dctList = new List <double[, ]>();

            foreach (var b in segm)
            {
                dctList.Add(DCT(b)); // список из коэффициентов ДКП
            }
            var        txtByte   = new List <byte>();
            List <int> possibPos = new List <int>(); // возможные позиции в соответствии с размером списка коэффициентов ДКП

            for (int i = 0; i < dctList.Count; i++)
            {
                possibPos.Add(i);
            }
            int  end     = 2; //конец прохода
            bool LenDone = true;

            for (int i = 0; i < end; i++)
            {
                var bits = new bool[8];     // булевый массив битов символа
                for (int j = 0; j < 8; j++)
                {
                    int pos = possibPos[0];     // позиция
                    possibPos.RemoveAt(0);
                    double AbsPoint1 = Math.Abs(dctList[pos][p1.X, p1.Y]);
                    double AbsPoint2 = Math.Abs(dctList[pos][p2.X, p2.Y]);
                    // бит выделяем в соответсвии с тем, какое абслютное значение больше
                    if (AbsPoint1 > AbsPoint2)
                    {
                        bits[j] = false;
                    }
                    else if (AbsPoint1 < AbsPoint2)
                    {
                        bits[j] = true;
                    }
                }
                txtByte.Add(CommonFunc.BoolArrByte(bits));
                if (i == 0 && txtByte.ToArray()[0] != Convert.ToByte('Z'))     // в случае отсутвия метки возвращаем пустую строку
                {
                    return("");
                }
                else if (i == 1)     //увеличиваем конец прохода, узнав размер длины
                {
                    end = txtByte.ToArray()[1] + 2;
                    txtByte.Clear();
                }
                else if (LenDone && i + 1 == end)   //увеличиваем конец прохода, узнав длину
                {
                    end += CommonFunc.IntBytes(txtByte);
                    txtByte.Clear();
                    LenDone = false;
                }
            }
            return(Encoding.GetEncoding(1251).GetString(txtByte.ToArray())); //преобразуем массив
        }
Пример #3
0
        // проверка на налчие скрытого текста
        public static bool IsHiddenText(StegoBitmap stgbmap, Colours c)
        {
            var bmap         = stgbmap.GetImage();
            int width        = bmap.Width;
            int height       = bmap.Height;
            var arrWhereHide = new byte[bmap.Width, bmap.Height]; // массив байтов, где будет хранится текст в соотвествии с выбранным цветом

            //выбираем из изображения пиксели в соответствии с переданным цветом
            for (int i = 0; i < bmap.Width; i++)
            {
                for (int j = 0; j < bmap.Height; j++)
                {
                    if (c == Colours.Red)
                    {
                        arrWhereHide[i, j] = bmap.GetPixel(i, j).R;
                    }
                    else if (c == Colours.Green)
                    {
                        arrWhereHide[i, j] = bmap.GetPixel(i, j).G;
                    }
                    else if (c == Colours.Blue)
                    {
                        arrWhereHide[i, j] = bmap.GetPixel(i, j).B;
                    }
                    else
                    {
                        throw new NullReferenceException();
                    }
                }
            }
            int numSegm = bmap.Width * bmap.Height / (SizeSegment * SizeSegment); //общее число сегментов
            var segm    = new List <byte[, ]>();

            Separate(arrWhereHide, segm, bmap.Width, bmap.Height, SizeSegment);// разбиваем массив на сегменты
            // дискретное косинусное преобразование
            var dctList = new List <double[, ]>();

            foreach (var b in segm)
            {
                dctList.Add(DCT(b)); // список из коэффициентов ДКП
            }
            var        txtByte   = new List <byte>();
            List <int> possibPos = new List <int>(); // возможные позиции в соответствии с размером списка коэффициентов ДКП

            for (int i = 0; i < dctList.Count; i++)
            {
                possibPos.Add(i);
            }
            var bits = new bool[8]; // булевый массив битов символа

            for (int j = 0; j < 8; j++)
            {
                int pos = possibPos[0]; // позиция
                possibPos.RemoveAt(0);
                if (ValidMoonotony(dctList[pos]) && ValidSharpness(dctList[pos]))
                {
                    double P1 = dctList[pos][p1.X, p1.Y];
                    double P2 = dctList[pos][p2.X, p2.Y];
                    double P3 = dctList[pos][p3.X, p3.Y];
                    //бит выделяем в соответсвии с тем, какое абслютное значение больше
                    if (Math.Min(P1, P2) - P3 >= 0.001)
                    {
                        bits[j] = false;
                    }
                    else if (P3 - Math.Max(P1, P2) >= 0.001)
                    {
                        bits[j] = true;
                    }

                    j++;
                }
                j--;
            }
            txtByte.Add(CommonFunc.BoolArrByte(bits));
            if (txtByte.ToArray()[0] != Convert.ToByte('B')) // в случае отсутвия метки возвращаем пустую строку
            {
                return(false);
            }
            return(true);
        }