Лабораторная работа № 9. Программирование алгоритма      сокрытия информации в графических файлах



Цель: получить навыки работы с растровой графикой

 

Теоретическая часть

Одним из эффективных методов обеспечения конфиденциальности информации является использование стеганографии. Наиболее распространенным методом скрытия информация является метод замены наименьших значащих битов или LSB-метод. Идея данного метода заключается в том, что изменение младших битов приводит к изменениям цвета пикселя не заметных для человека.

Данная работа посвящена реализации приложения, позволяющего скрывать информацию из файлов в графическое изображение формата BMP. Данный формат является одним из распространенных и простых для хранения растровой графической информации. В ОС Windows используются два типа растровых изображений: зависимые от устройства растровые изображения (DDB) и независимое от устройства растровое изображение (DIB).

Растровые изображения DIB формата содержат всю необходимую информацию вне зависимости от устройства, поэтому наиболее пригодны для хранения на диске.

При скрытии информации необходимо определить структуру размещения данных файле-контейнере. В работе предлагается следующая схема. Каждый байт информации разбивается на 3 части, как показано на рисунке 9.1.

Рисунок 9.1 – Схема разбиения байта

Приведенная схема разбиения позволяет сохранить 1 байт информации в 1 пиксел изображения, представленного в цветовой модели RGB. Каждый блок абайт данных сохраняется в одной из составляющей цвета модели RGB. Например, 1-ый блок – сохраняется в канале красного цвета, 2-ой блок – в канале синего цвета, 3-ий – в блоке зеленого.

На рисунке 9.2 представлена схема размещения данных в файле-контейнере.

Рисунок 9.2 – Схема размещения данных в файле контейнере

В первом пикселе рисунка размещена метка, которая сигнализирует о присутствии или отсутствии данных. Следующие в 4 пикселях закодирована информация о количестве байтов данных C, а в последующих C пикселях скрыты данные.

Для работы с растровыми изображениями в данной работе будут использоваться следующие основные элементы:

- Picture Control класса CStatic(для отображения изображения);

- класс CImage для загрузки и сохранения изображения.

Класс CImage обеспечивает работу с растровыми изображениями, включая возможность загрузки и сохранения изображений в форматах BMP, JPEG, GIF и PNG. В лабораторной работе будут использоваться следующие методы данного класса: Load, Save, BitBlt, StertchBlt, GetPixel и SetPixel.

Для загрузки растрового изображения используется метод Load:

HRESULT Load(LPCTSTR pszFileName),где pszFileName – имя файла-изображения.Аналогичный формат имеет метод  сохранения изображения Save. GetPixel и SetPixel используются для получения и установки цвета пикселя по координатам X и Y. Ниже приведен формат метода GetPixel :COLORREF GetPixel( int x, int y ).

Метод BitBlt  копирует растровое изображение из контекста устройства объекта класса CImage в контекст устройства другого устройства. Формат данного метода приведен ниже:

   BOOL BitBlt(HDC hDestDC, int xDest, int yDest, DWORD dwROP = SRCCOPY )

где hDestDC – дескриптор контекста устройства назанчения;

  xDest, yDest –координаты верхней левой вершины прямоугольника, куда копируется изображение;

   dwROP – тип растровой операции, определяющей  сочетание цветов источника и приемника. По умолчанию данный параметр имеет значение SRCCOPY, что предполагает установку цвета источника.

Пример копирования изображения из объекта класса CImage в элемент типа Picture Control приведен ниже:

CDC* pDC=m_picture.GetDC();//определяем контекст графического устройства

CRect cr;//переменная для хранения размеров элемента Pictrue Control

m_picture.GetClientRect(&cr);//определяем размеры

pImage.BitBlt(pDC->m_hDC,0,0,cr.Width(),cr.Height(),0,0,SRCCOPY);//копирование

//изображения

Для получения интенсивности цвета красного, зеленого и синего каналов используются соответственно следующие макросы: GetRValue, GetGValue и GetBValue. Формат GetRValue приведен ниже:

   BYTE GetRValue ( DWORD RGB);

Функция возвращает интенсивность красного компонента цвета, представленного в модели RGB. Аналогичный формат имеют и два других макроса.

 

Постановка задачи

 

Разработать приложение на основе диалоговых окон, позволяющее спрятать в графическом рисунке формата BMP информацию из файла.

Порядок выполнения работы

1. Создайте проект Lr9 на основе диалогового окна с использованием MFC.2. Разместите на диалоговом окне следующие элементы: Picture Control и 3 кнопки. Первая кнопка будет использовать для открытия файла с изображением, вторая кнопка для открытия файла источника данных, а третья – для чтения скрытой информации из изображения с последующим сохранением. Расположение элементов представлено на рисунке 9.3. Рисунок 9.3 – Экранная форма программы3. Измените свойство Type элемента Picture Control на значение Bitmap .4. Добавьте переменную управления m_picture в класс CLr9Dlg, связанную с элементом Picture Control. 5. Добавьте переменную m_Image типа CImage в класс CLr9Dlg.6. Напишите обработчик события нажатия первой кнопки, который открывает графический файл формата BMP при помощи переменной m_Iimage и отображает в элементе Picture Control:

TCHAR szFilters[]= _T("BitMap (*.bmp)|*.bmp||");

CFileDialog dlg(true,_T("BitMap"), _T("*.bmp"),

OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);

if (dlg.DoModal()==IDOK)

{

CDC* pDC=m_picture.GetDC();

if (!pImage.IsNull())

       pImage.Detach();

pImage.Load(dlg.GetPathName());

CRect cr;

m_picture.GetClientRect(&cr); pImage.BitBlt(pDC->m_hDC,0,0,cr.Width(),cr.Height(),0,0,SRCCOPY);}7. Напишите обработчик события второй кнопки, который открывает файл с информацией и скрывает его в графическом файле. Предусмотреть проверки, что файл-контейнер выбран и что размер рисунка достаточен для сохранения информации:

unsigned char buff[100];

TCHAR szFilters[]= _T("All (*.*)|*.*||");

CFileDialog dlg(true,_T("All"), _T("*.*"),

OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);

char szFiltersSave[]="BitMap (*.bmp)|*.bmp||";

CFileDialog dlgsave(false,"BitMap", "*.bmp",

       OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFiltersSave);

if (dlg.DoModal()==IDOK)//выбор файла с информацией

{

       CFile file;

       if (!file.Open(dlg.GetPathName(),CFile::modeRead|CFile::typeBinary))

       {

             AfxMessageBox("Не удалось открыть файл");

             return;

       }

       CString str;

       int count=0;

       bool bOk=true;

       if (file.GetLength()>((pImage.GetWidth()*pImage.GetHeight()-5)))

       {

       AfxMessageBox("Не досточный размер контейнера для скрытия информации!!!");

             goto lClose;

       }

InitStep();//инициализирует переменные для хранения строки и столбца рисунка

WriteFirstChar();// скрывает в первый пиксель метку

       int len=file.GetLength();

       WriteLength(&len);//записываем в 4 пикселя размер файла информации

       do

       {

count=file.Read(buff,sizeof(buff));//считываем из файла с //информацией 100 байтов

if (!WriteStrToBmp(buff,count))//функция скрывает данные из буфер в //рисунок

             {

                   bOk=false;

                   break;

             }

       }

       while (count>0);

       if (dlgsave.DoModal()==IDOK)// сохранение в файл рисунка со скрытой //информацией

       {

             pImage.Save(dlgsave.GetPathName());

 

}

if (!bOk)

             AfxMessageBox("Произошли ошибки при сохранении информации");

lClose:

         file.Close();8. Напишите обработчик события третьей кнопки, который считывает скрытую информацию из графического рисунка и сохраняет на диск:

InitStep();

unsigned char ch=ReadByte();

if (ch!=10)//проверка наличии метки

{

       AfxMessageBox("Нет данных в изображении!!!");

       return ;

}

if (!NextStep())//переход к следующему пикселю

{

       AfxMessageBox("Ошибка!!!");

       return ;

}

int cnt=ReadLen();//извлечение количества байтов информации

if (cnt==-1)

{

       AfxMessageBox("Ошибка!!!");

       return ;

}

TCHAR szFilters[]= _T("Text (*.txt)|*.txt||");

CFileDialog dlg(false,_T("Text"), _T("*.txt"),

OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);

if (dlg.DoModal()==IDOK)//выбор файла для сохранения информации

{

       CFile file;

if (!file.Open(dlg.GetPathName(),CFile::modeCreate|

CFile::modeWrite|CFile::typeBinary))

       {

       AfxMessageBox("Не удалось создать файл, для сохранения результата");

             return;

       }

       int cntwr;

       for (int i=0;i<cnt;i++)

       {

       ch=ReadByte();// извлечение байта информации из текущего пискеля

             file.Write(&ch,1);

             if (!NextStep())

             {

                   AfxMessageBox("Ошибка!!!");

                   file.Close();

                   return ;

             }

       }

       file.Close();

 

}9. Проверьте работу программы.10. Ответьте на контрольные вопросы и составить отчет по работе.

Контрольные вопросы

 

1. Опишите метод скрытия информации LSB.

2. Какие изображения относятся к классу DIB?

3. Назначение метода GetPixel класса CImage.

4. Как узнать, если в рисунке информация?

5. Назначение метода GetRValue.

 

Список использованных источников

 

1. Лафоре, Р. Объектно-ориентированное программирование в C++. Классика Computer Science / Р. Лафоре. – СПб.: Питер, 2008. – 928 с.

2. Литвиненко, Н.А. Технология программирования на С++. Win 32 API-приложения/Н.А. Литвиненко. – БХВ–Петербург, 2010. – 288 с.

3. Павловская, Т.А. C/C++. Программирование на языке высокого уровня / Т. А. Павловская. – СПб.: Питер, 2003. – 461 с.

4. Свиркин, М. Программирование под Windows в среде Visual C++ 2005/ М. Свиркин, А. Чуркин, В. Соковикова [Электронный ресурс].– Режим доступа: http://www.intuit.ru/studies/courses/495/351/info/

5. Хортон Айвор. Visual C++2010:полный курс/А. Хортон: пер. с англ. –М.: ООО «И.Д. Вильямс», 2011.-1216 с.

6.  MSDN – Windows API. Персональный сайт Владимира Соковикова [Электронный ресурс].– Режим доступа: http://vsokovikov.narod.ru/.

7.  Библиотека MSDN [Электронный ресурс].– Режим доступа:. http://msdn.microsoft.com/ru-ru/library/ms123401.aspx

8.  Поляков А. Методы и алгоритмы компьютерной графики в примерах на Visual C++, 2 изд. / А. Поляков, В. Брусенцев. – СПб.: БХВ-Петербург, 2010.

 


Приложение А

(обязательное)

Листинг программы

// Win32_API.cpp: определяет точку входа для приложения.

#include "stdafx.h"

#include "Win32_API.h"

#define MAX_LOADSTRING 100

// Глобальные переменные:

HINSTANCE hInst;                                              // текущий экземпляр

TCHAR szTitle[MAX_LOADSTRING];                         // Текст строки заголовка

TCHAR szWindowClass[MAX_LOADSTRING];             // имя класса главного окна

// Отправить объявления функций, включенных в этот модуль кода:

ATOM                  MyRegisterClass(HINSTANCE hInstance);

BOOL                  InitInstance(HINSTANCE, int);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,

                int  nCmdShow)

{

  UNREFERENCED_PARAMETER(hPrevInstance);

  UNREFERENCED_PARAMETER(lpCmdLine);

  // TODO: разместите код здесь.

  MSG msg;

  HACCEL hAccelTable;

  // Инициализация глобальных строк

  LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

  LoadString(hInstance, IDC_WIN32_API, szWindowClass, MAX_LOADSTRING);

  MyRegisterClass(hInstance);

  // Выполнить инициализацию приложения:

  if (!InitInstance (hInstance, nCmdShow))

  {

        return FALSE;

  }

  hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32_API));

  // Цикл основного сообщения:

  while (GetMessage(&msg, NULL, 0, 0))

  {

        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

        {

               TranslateMessage(&msg);

               DispatchMessage(&msg);

        }

  }

  return (int) msg.wParam;

}

ATOM MyRegisterClass(HINSTANCE hInstance)

{

  WNDCLASSEX wcex;

  wcex.cbSize = sizeof(WNDCLASSEX);

  wcex.style            = CS_HREDRAW | CS_VREDRAW;

  wcex.lpfnWndProc = WndProc;

  wcex.cbClsExtra       = 0;

  wcex.cbWndExtra       = 0;

  wcex.hInstance        = hInstance;

  wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32_API));

  wcex.hCursor   = LoadCursor(NULL, IDC_ARROW);

  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

  wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32_API);

  wcex.lpszClassName = szWindowClass;

  wcex.hIconSm   = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

  return RegisterClassEx(&wcex);

}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

HWND hWnd;

hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)

{

return FALSE;

}

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

return TRUE;

}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

  int wmId, wmEvent;

  PAINTSTRUCT ps;

  HDC hdc;

  switch (message)

  {

  case WM_COMMAND:

        wmId = LOWORD(wParam);

        wmEvent = HIWORD(wParam);

        // Разобрать выбор в меню:

        switch (wmId)

        {

        case IDM_ABOUT:

               DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

               break;

        case IDM_EXIT:

               DestroyWindow(hWnd);

               break;

        default:

               return DefWindowProc(hWnd, message, wParam, lParam);

        }

        break;

  case WM_PAINT:

        hdc = BeginPaint(hWnd, &ps);

        EndPaint(hWnd, &ps);

        break;

  case WM_DESTROY:

        PostQuitMessage(0);

        break;

  default:

        return DefWindowProc(hWnd, message, wParam, lParam);

  }

  return 0; }

// Обработчик сообщений для окна "О программе".

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

  UNREFERENCED_PARAMETER(lParam);

  switch (message)

  {

  case WM_INITDIALOG:

        return (INT_PTR)TRUE;

 

  case WM_COMMAND:

        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)

        {

               EndDialog(hDlg, LOWORD(wParam));

               return (INT_PTR)TRUE;

        }

        break;

  }

  return (INT_PTR)FALSE;}


Дата добавления: 2019-09-13; просмотров: 382; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!