找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3674|回复: 0

[原]VC++信息安全编程(14)基于24位bmp位图的信息隐藏

[复制链接]
发表于 2012-3-8 15:02:45 | 显示全部楼层 |阅读模式
信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是透明的。
传统的信息隐藏起源于古老的隐写术。如在古希腊战争中,为了安全地传送军事情报,奴隶主剃光奴隶 的头发,将情报文在奴隶的头皮上,待头发长起后再派出去传送消息。我国古代也早有以藏头诗、藏尾诗、漏格诗以及绘画等形式,将要表达的意思和“密语”隐藏在诗文或画卷中的特定位置,一般人只注意诗或画的表面意境,而不会去注意或破解隐藏其中的密语。   信息隐藏的发展历史可以一直追溯到"匿形术(Steganography)"的使用。"匿形术"一词来源于古希腊文中"隐藏的"和"图形"两个词语的组合。虽然"匿形术"与"密码术(Cryptography)"都是致力于信息的保密技术,但是,两者的设计思想却完全不同。"密码术"主要通过设计加密技术,使保密信息不可读,但是对于非授权者来讲,虽然他无法获知保密信息的具体内容,却能意识到保密信息的存在。而"匿形术"则致力于通过设计精妙的方法,使得非授权者根本无从得知保密信息的存在与否。相对于现代密码学来讲,信息隐藏的最大优势在于它并不限制对主信号的存取和访问,而是致力于签字信号的安全保密性。


我们进行信息交换的时候,需要保证数据的安全,所以需要进行适当的信息隐藏。
我们发送一个图片。但是图片里面隐含的加密信息,是就是信息隐藏,只有专属工具能够读出。
所以信息隐藏技术很重要。针对信息安全。
我们来实现一个案例代码。
BMP图信息隐藏头文件,请见代码分析
  1. // BMPHider.h: interface for the CBMPHider class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_BMPHIDER_H__6287D87F_F0AA_4D0C_9502_4674B639CBB5__INCLUDED_)
  5. #define AFX_BMPHIDER_H__6287D87F_F0AA_4D0C_9502_4674B639CBB5__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include <complex>
  10. using namespace std;
  11. class CBMPHider  
  12. {
  13. public:
  14.         CBMPHider();
  15.         virtual ~CBMPHider();
  16. public:
  17.         int m_BitCount;                        //位图的图像位数
  18.         WORD * m_pWordData;
  19.         CPalette m_Palette;
  20.         unsigned char *m_pDib, *m_pDibBits;
  21.         unsigned char *m_pOldDibShow;
  22.         DWORD m_dwDibSize;
  23.         BITMAPINFOHEADER *m_pBIH;
  24.         RGBQUAD *m_pPalette;
  25.         int m_nPaletteEntries;
  26.         UINT bitmap_size;
  27.         UINT embfile_size;
  28.         unsigned char *p;                //指向宿主图像数据
  29.         int tag;                                //此tag用以标记打开的图像中是否含有隐藏信息0:无 else:有
  30.         unsigned char *q;                //指向隐藏文件数据
  31.         unsigned char *m_pFile;
  32. public:
  33.         BOOL Draw( CDC *pDC, int nX = -1, int nY = -1, int nWidth = -1, int nHeight = -1, int Style = 1);
  34.         BOOL Save( const char *pszFilename );
  35.         BOOL Load( const char * );
  36.        
  37.         void BackUpDib();                //备份图像
  38.         void Pick();                        //提取图像
  39.         void Embed();                        //嵌入图像
  40.         BOOL LoadEmbFile(const char *);
  41.         BOOL DrawContrast(CDC *pDC,int rect_width, int rect_height);
  42.         void SavePicked( const char *pszFilename );       
  43. };
  44. #endif // !defined(AFX_BMPHIDER_H__6287D87F_F0AA_4D0C_9502_4674B639CBB5__INCLUDED_)
  45. 请见详细代码实现
  46. #include "stdafx.h"
  47. #include "BMPHider.h"
  48. //////////////////////////////////////////////////////////////////////
  49. // Construction/Destruction
  50. //////////////////////////////////////////////////////////////////////
  51. CBMPHider::CBMPHider()
  52. {
  53.         m_pDib = NULL;
  54.         m_pWordData = NULL;
  55.         m_pFile = NULL;
  56.         m_pOldDibShow = NULL;
  57. }
  58. CBMPHider::~CBMPHider()
  59. {
  60.         if( m_pDib != NULL )
  61.                 delete [] m_pDib;
  62.         if( m_pWordData != NULL )
  63.                 delete [] m_pWordData;
  64.         if (m_pFile != NULL)
  65.                 delete [] m_pFile;
  66.         if (m_pOldDibShow != NULL)
  67.                 delete [] m_pOldDibShow;
  68. }
  69. BOOL CBMPHider::Load( const char *pszFilename )
  70. {
  71.         CFile cf;
  72.         if( !cf.Open( pszFilename, CFile::modeRead ) )
  73.                 return( FALSE );
  74.        
  75.         DWORD dwDibSize;
  76.         dwDibSize =
  77.                 cf.GetLength() - sizeof( BITMAPFILEHEADER );
  78.         unsigned char *pDib;
  79.         pDib = new unsigned char [dwDibSize];
  80.         if( pDib == NULL )
  81.                 return( FALSE );
  82.         BITMAPFILEHEADER BFH;
  83.         try
  84.         {
  85.                 if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
  86.                         != sizeof( BITMAPFILEHEADER ) ||
  87.                         BFH.bfType != 'MB' ||
  88.                         cf.Read( pDib, dwDibSize ) != dwDibSize )
  89.                 {
  90.                         delete [] pDib;
  91.                         return( FALSE );
  92.                 }
  93.         }
  94.        
  95.         catch( CFileException *e )
  96.         {
  97.                 e->Delete();
  98.                 delete [] pDib;
  99.                 return( FALSE );
  100.         }
  101.         cf.Close();
  102.         if( m_pDib != NULL )
  103.                 delete m_pDib;
  104.         if (BFH.bfReserved1 != 0)          //含有隐藏信息,保存其大小
  105.         {
  106.                 if (BFH.bfReserved2 == 0)
  107.                         embfile_size = BFH.bfReserved1;
  108.                 else
  109.                         embfile_size = BFH.bfReserved1 + 65535;
  110.         }
  111.         m_pDib = pDib;
  112.         m_dwDibSize = dwDibSize;
  113.         m_pBIH = (BITMAPINFOHEADER *) m_pDib;
  114.         m_pPalette =(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
  115.         m_nPaletteEntries = 1 << m_pBIH->biBitCount;
  116.         if( m_pBIH->biBitCount > 8 )         
  117.                 m_nPaletteEntries = 0;
  118.         else if( m_pBIH->biClrUsed != 0 )
  119.                 m_nPaletteEntries = m_pBIH->biClrUsed;
  120.         m_pDibBits = &m_pDib[sizeof(BITMAPINFOHEADER)+
  121.                         m_nPaletteEntries*sizeof(RGBQUAD)];
  122.         if( m_Palette.GetSafeHandle() != NULL )
  123.                 m_Palette.DeleteObject();
  124.         if( m_nPaletteEntries != 0 )
  125.         {      
  126.                 LOGPALETTE *pLogPal = (LOGPALETTE *) new char
  127.                                 [sizeof(LOGPALETTE)+
  128.                                 m_nPaletteEntries*sizeof(PALETTEENTRY)];
  129.                 if( pLogPal != NULL )
  130.                 {
  131.                         pLogPal->palVersion = 0x300;
  132.                         pLogPal->palNumEntries = m_nPaletteEntries;
  133.                         for( int i=0; i<m_nPaletteEntries; i++ )
  134.                         {
  135.                                 pLogPal->palPalEntry[i].peRed =
  136.                                         m_pPalette[i].rgbRed;
  137.                                 pLogPal->palPalEntry[i].peGreen =
  138.                                         m_pPalette[i].rgbGreen;
  139.                                 pLogPal->palPalEntry[i].peBlue =
  140.                                         m_pPalette[i].rgbBlue;
  141.                         }
  142.                         m_Palette.CreatePalette( pLogPal );
  143.                         delete [] pLogPal;
  144.                 }
  145.         }
  146.         m_BitCount = 24;             //24位位图
  147.         p = m_pDibBits;              //指向位图数据的指针,用来执行处理操作用
  148.         bitmap_size = m_dwDibSize - (m_pDibBits - m_pDib);//真正的位图数据的大小(即除头结构外)
  149.        
  150.         tag = BFH.bfReserved1;
  151.         return( TRUE );
  152. }
  153. BOOL CBMPHider::Save( const char *pszFilename ) //保存含有隐藏信息的bmp
  154. {
  155.         if( m_pDib == NULL )
  156.                 return( FALSE );
  157.         CFile cf;
  158.         if( !cf.Open( pszFilename,
  159.                 CFile::modeCreate | CFile::modeWrite ) )
  160.                 return( FALSE );
  161.         try
  162.         {
  163.                 BITMAPFILEHEADER BFH;
  164.                 memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
  165.                 BFH.bfType = 'MB';
  166.                 BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
  167.                 BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
  168.                         sizeof( BITMAPINFOHEADER ) +
  169.                         m_nPaletteEntries * sizeof( RGBQUAD );
  170.                 if (embfile_size <= 65535)   
  171.                         //由于bfReserved1是unsigned short型的,大小可能不能满足要求,可能要用到reserved2
  172.                         BFH.bfReserved1 = embfile_size;   
  173.                 else
  174.                 {
  175.                         BFH.bfReserved1 = embfile_size - 65535;
  176.                         BFH.bfReserved2 = 1; //标记
  177.                 }
  178.                 cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
  179.                 cf.Write( m_pDib, m_dwDibSize );
  180.         }
  181.         catch( CFileException *e )
  182.         {
  183.                 e->Delete();
  184.                 return( FALSE );
  185.         }
  186.         return( TRUE );
  187. }
  188. BOOL CBMPHider::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style )
  189. {
  190.         if( m_pDib == NULL )
  191.                 return( FALSE );
  192.         long vWidth = m_pBIH->biWidth;
  193.         if( nWidth == -1 )
  194.                 nWidth = m_pBIH->biWidth;
  195.         if( nHeight == -1 )
  196.                 nHeight = m_pBIH->biHeight;
  197.         if (Style)   
  198.         {
  199.                 StretchDIBits( pDC->m_hDC, nX, nY,
  200.                         nWidth, nHeight,
  201.                         0, 0,
  202.                         m_pBIH->biWidth, m_pBIH->biHeight,
  203.                         m_pDibBits,
  204.                         (BITMAPINFO *) m_pBIH,
  205.                         BI_RGB, SRCCOPY );
  206.         }
  207.         else
  208.         {
  209.                 SetDIBitsToDevice( pDC->m_hDC, nX, nY,
  210.                         m_pBIH->biWidth, m_pBIH->biHeight,
  211.                         0, 0,
  212.                         0, m_pBIH->biHeight,
  213.                         m_pDibBits,
  214.                         (BITMAPINFO *) m_pBIH,
  215.                         BI_RGB);
  216.         }
  217.         return( TRUE );
  218. }
  219. BOOL CBMPHider::LoadEmbFile(const char * pszFilename)
  220. {       
  221.         CFile cf;
  222.         if( !cf.Open( pszFilename, CFile::modeRead ) )
  223.                 return( FALSE );
  224.         DWORD dwFileSize;
  225.         dwFileSize = cf.GetLength();
  226.         embfile_size = dwFileSize;
  227.         unsigned char *pFile;
  228.         pFile = new unsigned char [dwFileSize];
  229.         cf.Read( pFile, dwFileSize );       //将文件中内容读入数组,解下来就开始嵌入操作
  230.         m_pFile = pFile;
  231.         q = pFile;        //记录下位置
  232.         return true;
  233. }
  234. void CBMPHider::Embed()//嵌入
  235. {
  236.         unsigned char bmdata;//bitmap data
  237.         unsigned char efdata;//embeddedfile data
  238.         int t = 7;               
  239.         int x[8];       
  240.         int s[8];
  241.         int last_bit; //记录字节最低位本来的bit
  242.         for(UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
  243.         {
  244.                 bmdata = *p;
  245.                 for (int j = 0; j <= 7; j++) //计算各bit位
  246.                 {
  247.                         x[j] = bmdata & 1;
  248.                         bmdata >>= 1;
  249.                 }
  250.                
  251.                 last_bit = x[0];
  252.                 x[0] = x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
  253.                
  254.                 if (t == 7)    //宿主图片每走过八个字节,计算一次s[]
  255.                 {
  256.                         efdata = *q;
  257.                         for (j = 0; j <= 7; j++)
  258.                         {
  259.                                 s[j] = efdata & 1;
  260.                                 efdata >>= 1;
  261.                         }
  262.                 }
  263.                 x[0] ^= s[t];//隐藏信息
  264.                 if (last_bit == 0)  //嵌入隐藏信息
  265.                 {
  266.                         *p |= x[0];
  267.                 }
  268.                 else
  269.                 {
  270.                         *p &= 254 + x[0];
  271.                 }
  272.        
  273.                 p++;
  274.                 t--;
  275.                 if (t == -1)  //需要计算一次s[]
  276.                 {
  277.                         t = 7;
  278.                         q++;
  279.                         i2++;
  280.                 }
  281.         }
  282. }
  283. void CBMPHider::Pick()//提取
  284. {
  285.         m_pFile = new unsigned char [embfile_size];
  286.         unsigned char *q = m_pFile;
  287.         unsigned char bmdata;//bitmap data
  288.         int x[8];       
  289.         int s[8];
  290.         int t = 7;
  291.         for (UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
  292.         {
  293.                 bmdata = *p;
  294.                 for (int j = 0; j <= 7; j++) //计算各bit位
  295.                 {
  296.                         x[j] = bmdata & 1;
  297.                         bmdata >>= 1;
  298.                 }
  299.                 s[t] = x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
  300.                 t--;
  301.                 if (t == -1) //s[7]到s[0]组成一个字节
  302.                 {
  303.                         *q = s[7] * 128 + s[6] * 64 + s[5] * 32 + s[4] * 16 +
  304.                                 s[3] * 8 + s[2] * 4 + s[1] * 2 + s[0];
  305.                         t = 7;
  306.                         i2++;
  307.                         q++;
  308.                 }
  309.                 p++;
  310.         }
  311. }
  312.        
  313. void CBMPHider::SavePicked( const char *pszFilename )
  314. {
  315.         CFile cf;
  316.         cf.Open( pszFilename, CFile::modeCreate | CFile::modeWrite );
  317.         cf.Write( m_pFile, embfile_size );
  318. }
  319. void CBMPHider::BackUpDib()
  320. {
  321.         m_pOldDibShow = new unsigned char [bitmap_size];
  322.    
  323.         ::CopyMemory(m_pOldDibShow, m_pDibBits, bitmap_size); //将原始的数据单独保存以便对比显示
  324. }
  325. BOOL CBMPHider::DrawContrast(CDC *pDC, int rect_width, int rect_height)
  326. {                             //看原图,如果容纳得下两个图,则不要压缩,否则要压缩
  327.         if (m_pOldDibShow == NULL)
  328.                 return FALSE;
  329.         if (rect_width >= 2*m_pBIH->biWidth + 30 && rect_height >= m_pBIH->biHeight)
  330.         {
  331.                 StretchDIBits( pDC->m_hDC, 0, 0,
  332.                 m_pBIH->biWidth, m_pBIH->biHeight,
  333.                 0, 0,
  334.                 m_pBIH->biWidth, m_pBIH->biHeight,
  335.                 m_pOldDibShow,
  336.                 (BITMAPINFO *) m_pBIH,
  337.                 BI_RGB, SRCCOPY );    // 原图
  338.                 StretchDIBits( pDC->m_hDC, m_pBIH->biWidth+30, 0,
  339.                 m_pBIH->biWidth, m_pBIH->biHeight,
  340.                 0, 0,
  341.                 m_pBIH->biWidth, m_pBIH->biHeight,
  342.                 m_pDibBits,
  343.                 (BITMAPINFO *) m_pBIH,
  344.                 BI_RGB, SRCCOPY );    // 嵌入隐藏信息的图
  345.         }
  346.         else
  347.         {
  348.                 int scale_i = m_pBIH->biWidth * 5 / (rect_width*2);
  349.                 int scale_j = m_pBIH->biHeight / rect_height;
  350.                 if (scale_i < scale_j)
  351.                         scale_i = scale_j;
  352.                 StretchDIBits( pDC->m_hDC, 0, 0,
  353.                 m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
  354.                 0, 0,
  355.                 m_pBIH->biWidth, m_pBIH->biHeight,
  356.                 m_pOldDibShow,
  357.                 (BITMAPINFO *) m_pBIH,
  358.                 BI_RGB, SRCCOPY );    // 原图
  359.                 StretchDIBits( pDC->m_hDC, m_pBIH->biWidth / scale_i+30, 0,
  360.                 m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
  361.                 0, 0,
  362.                 m_pBIH->biWidth, m_pBIH->biHeight,
  363.                 m_pDibBits,
  364.                 (BITMAPINFO *) m_pBIH,
  365.                 BI_RGB, SRCCOPY );    // 嵌入隐藏信息的图
  366.         }
  367.         return TRUE;
  368. }
  369. 具体代码调用实现
  370. #include "stdafx.h"
  371. #include "DataHideInBMP.h"
  372. #include "DataHideInBMPDoc.h"
  373. #include "DataHideInBMPView.h"
  374. #ifdef _DEBUG
  375. #define new DEBUG_NEW
  376. #undef THIS_FILE
  377. static char THIS_FILE[] = __FILE__;
  378. #endif
  379. /////////////////////////////////////////////////////////////////////////////
  380. // CDataHideInBMPView
  381. IMPLEMENT_DYNCREATE(CDataHideInBMPView, CView)
  382. BEGIN_MESSAGE_MAP(CDataHideInBMPView, CView)
  383.         //{{AFX_MSG_MAP(CDataHideInBMPView)
  384.         ON_COMMAND(ID_NORMAL, OnNormal)
  385.         ON_COMMAND(ID_STRETCH, OnStretch)
  386.         ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
  387.         ON_COMMAND(ID_EMBED, OnEmbed)
  388.         ON_UPDATE_COMMAND_UI(ID_EMBED, OnUpdateEmbed)
  389.         ON_COMMAND(ID_PICK, OnPick)
  390.         ON_UPDATE_COMMAND_UI(ID_PICK, OnUpdatePick)
  391.         //}}AFX_MSG_MAP
  392.         // Standard printing commands
  393.         ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  394.         ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  395.         ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  396. END_MESSAGE_MAP()
  397. /////////////////////////////////////////////////////////////////////////////
  398. // CDataHideInBMPView construction/destruction
  399. CDataHideInBMPView::CDataHideInBMPView()
  400. {
  401.         // TODO: add construction code here
  402.         ImageStyle = 0;
  403.     have_open_a_file = false;
  404.         embed = false;
  405.         pick = false;
  406.         show_contrast = false;
  407. }
  408. CDataHideInBMPView::~CDataHideInBMPView()
  409. {
  410. }
  411. BOOL CDataHideInBMPView::PreCreateWindow(CREATESTRUCT& cs)
  412. {
  413.         // TODO: Modify the Window class or styles here by modifying
  414.         //  the CREATESTRUCT cs
  415.         WNDCLASSEX wndcls;
  416.         wndcls.cbSize=sizeof(WNDCLASSEX);
  417.         HINSTANCE hinst=AfxGetInstanceHandle();
  418.         if(CView::PreCreateWindow(cs)&&cs.lpszClass!=NULL)
  419.         {
  420.                 HBRUSH hbkbrush=CreateSolidBrush(RGB(0,0,0));
  421.                 if(!GetClassInfoEx(hinst,cs.lpszClass,&wndcls))
  422.                         return FALSE;
  423.                 UnregisterClass(cs.lpszClass,hinst);
  424.                 wndcls.hbrBackground=hbkbrush;
  425.                 RegisterClassEx(&wndcls);  
  426.                 return TRUE;
  427.         }
  428.         else
  429.                 return FALSE;
  430.         return CView::PreCreateWindow(cs);
  431. }
  432. /////////////////////////////////////////////////////////////////////////////
  433. // CDataHideInBMPView drawing
  434. void CDataHideInBMPView::OnDraw(CDC* pDC)
  435. {
  436.         CDataHideInBMPDoc* pDoc = GetDocument();
  437.         ASSERT_VALID(pDoc);
  438.         // TODO: add draw code for native data here
  439.         RECT Rect;
  440.         GetClientRect( &Rect );
  441.         if (!show_contrast)
  442.                 m_BMPHider.Draw( pDC, 0, 0, Rect.right, Rect.bottom, ImageStyle );
  443.         else
  444.         {
  445.                 m_BMPHider.DrawContrast(pDC, Rect.right, Rect.bottom);
  446.                 pDC->SetBkColor((0,0,0));
  447.                 pDC->SetTextColor((255,255,255));
  448.                 pDC->TextOut(0, Rect.bottom-30, "左图为原始图,右图为嵌入了隐藏信息的图");
  449.         }
  450. }
  451. /////////////////////////////////////////////////////////////////////////////
  452. // CDataHideInBMPView printing
  453. BOOL CDataHideInBMPView::OnPreparePrinting(CPrintInfo* pInfo)
  454. {
  455.         // default preparation
  456.         return DoPreparePrinting(pInfo);
  457. }
  458. void CDataHideInBMPView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  459. {
  460.         // TODO: add extra initialization before printing
  461. }
  462. void CDataHideInBMPView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  463. {
  464.         // TODO: add cleanup after printing
  465. }
  466. /////////////////////////////////////////////////////////////////////////////
  467. // CDataHideInBMPView diagnostics
  468. #ifdef _DEBUG
  469. void CDataHideInBMPView::AssertValid() const
  470. {
  471.         CView::AssertValid();
  472. }
  473. void CDataHideInBMPView::Dump(CDumpContext& dc) const
  474. {
  475.         CView::Dump(dc);
  476. }
  477. CDataHideInBMPDoc* CDataHideInBMPView::GetDocument() // non-debug version is inline
  478. {
  479.         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDataHideInBMPDoc)));
  480.         return (CDataHideInBMPDoc*)m_pDocument;
  481. }
  482. #endif //_DEBUG
  483. /////////////////////////////////////////////////////////////////////////////
  484. // CDataHideInBMPView message handlers
  485. void CDataHideInBMPView::OnNormal()
  486. {
  487.         // TODO: Add your command handler code here
  488.         ImageStyle = 0;
  489.         CMenu *pMnu = AfxGetMainWnd()->GetMenu( );
  490.         pMnu->CheckMenuItem(ID_STRETCH,MF_UNCHECKED);
  491.         pMnu->CheckMenuItem(ID_NORMAL,MF_CHECKED);
  492.        
  493.         InvalidateRect( NULL, TRUE );
  494.         UpdateWindow();       
  495. }
  496. void CDataHideInBMPView::OnStretch()
  497. {
  498.         // TODO: Add your command handler code here
  499.         ImageStyle = 1;
  500.        
  501.         CMenu *pMnu = AfxGetMainWnd()->GetMenu( );
  502.         pMnu->CheckMenuItem(ID_STRETCH,MF_CHECKED);
  503.         pMnu->CheckMenuItem(ID_NORMAL,MF_UNCHECKED);
  504.        
  505.         InvalidateRect( NULL, TRUE );
  506.         UpdateWindow();       
  507. }
  508. void CDataHideInBMPView::OnFileOpen()
  509. {
  510.         // TODO: Add your command handler code here
  511.         show_contrast = false;   //非对比显示
  512.         static char szFilter[] = "BMP Files(*.BMP)|*.BMP||";
  513.         CFileDialog FileDlg( TRUE, NULL, NULL,
  514.                 OFN_HIDEREADONLY, szFilter );
  515.         if( FileDlg.DoModal() == IDOK &&
  516.                 m_BMPHider.Load( FileDlg.GetPathName() ) )
  517.         {
  518.                 InvalidateRect( NULL, TRUE );
  519.                 UpdateWindow();
  520.                 have_open_a_file=true;
  521.                 if (m_BMPHider.tag == 0)//该图无隐藏信息
  522.                 {
  523.                         embed = true;
  524.                         pick = false;  //菜单亮暗控制
  525.                 }//
  526.                 else
  527.                 {
  528.                         embed = false;
  529.                         pick = true;  //菜单亮暗控制
  530.                 }//
  531.         }       
  532. }
  533. void CDataHideInBMPView::OnEmbed()
  534. {
  535.         // TODO: Add your command handler code here
  536.         //弹出打开对话框,用户选择嵌入的文件
  537.         static char szFilter[] = "All Files(*.*)|*.*||";
  538.         CFileDialog FileDlg( TRUE, NULL, NULL,
  539.                 OFN_HIDEREADONLY, szFilter );
  540.         if( FileDlg.DoModal() == IDOK &&
  541.                 m_BMPHider.LoadEmbFile( FileDlg.GetPathName() ) )
  542.         {
  543.                 if (m_BMPHider.bitmap_size / m_BMPHider.embfile_size < 8)
  544.                 {
  545.                         AfxMessageBox("文件太大,无法嵌入!");
  546.                 }
  547.                 else
  548.                 {
  549.                         show_contrast = true;
  550.                         m_BMPHider.BackUpDib(); //图片原始数据备份供对比显示
  551.                         m_BMPHider.Embed();   //嵌入
  552.                        
  553.                         Invalidate(true);//刷屏,显示加入隐藏信息后的图像
  554.                        
  555.                         static char szFilter[] = "BMP Files(*.BMP)|*.BMP||";
  556.                         CFileDialog FileDlg( FALSE, "bmp", NULL,                //保存
  557.                                 OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter );
  558.                        
  559.                         if( FileDlg.DoModal() == IDOK )
  560.                         {
  561.                                 m_BMPHider.Save( FileDlg.GetPathName() );
  562.                         }
  563.                         embed = false;
  564.                 }
  565.                
  566.         }       
  567. }
  568. void CDataHideInBMPView::OnUpdateEmbed(CCmdUI* pCmdUI)
  569. {
  570.         // TODO: Add your command update UI handler code here
  571.         pCmdUI->Enable(embed);       
  572. }
  573. void CDataHideInBMPView::OnPick()
  574. {
  575.         // TODO: Add your command handler code here
  576.         //提取完毕,弹出保存对话框,用户进行保存
  577.         static char szFilter[] = "All Files(*.*)|*.*||";
  578.         CFileDialog FileDlg( FALSE, "", NULL,                //保存
  579.                 OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter );
  580.                                
  581.         if (FileDlg.DoModal() == IDOK)
  582.         {       
  583.                 m_BMPHider.Pick();
  584.                 m_BMPHider.SavePicked(FileDlg.GetPathName());
  585.                 pick = false;
  586.         }       
  587. }
  588. void CDataHideInBMPView::OnUpdatePick(CCmdUI* pCmdUI)
  589. {
  590.         // TODO: Add your command update UI handler code here
  591.         pCmdUI->Enable(pick);       
  592. }
复制代码


作者:yincheng01 发表于2011-12-15 7:40:27 原文链接

您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-3 18:13 , Processed in 0.018872 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表