?? watermarking.cpp
字號:
// ************************************************************************
// 文件名:WaterMarking.cpp
//
// 水印添加函數庫:
//
// Set() - 水印嵌入函數
// Get() - 水印檢測函數
//
// ************************************************************************
#include "stdafx.h"
#include "dip_system.h"
#include "WaterMarking.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WIDTH 100
#define HEIGHT 100
/////////////////////////////////////////////////////////////////////////////
// CWaterMarking
CWaterMarking::CWaterMarking()
{
}
CWaterMarking::~CWaterMarking()
{
}
BEGIN_MESSAGE_MAP(CWaterMarking, CWnd)
//{{AFX_MSG_MAP(CWaterMarking)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWaterMarking message handlers
/*************************************************************************
*
* 函數名稱:
* Set()
*
* 參數:
* HDIB hDIB - 待處理的DIB
*
* 返回值:
* void - 無返回值
*
* 說明:
* 該函數為DIB圖象添加水印
*
************************************************************************/
void CWaterMarking::Set(HDIB hDIB)
{
// 指向DIB的指針
LPBYTE lpDIB;
// 指向DIB象素指針
LPBYTE lpDIBBits;
// 鎖定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB圖像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判斷是否是24-bpp位圖
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用戶
MessageBox("請先將其轉換為24位色位圖,再進行處理!", "系統提示" , MB_ICONINFORMATION | MB_OK);
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光標形狀
BeginWaitCursor();
// DIB的寬度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 計算圖像每行的字節數
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 從水印文件獲取相關信息
char exeFullPath[MAX_PATH];
CString strPath;
GetModuleFileName(NULL, exeFullPath, MAX_PATH);
strPath = CString(exeFullPath);
strPath = strPath.Left(strPath.ReverseFind('\\'));
strPath += "\\水印.bmp";
CFile file;
file.Open(strPath, CFile::modeReadWrite);
int nFileLen = file.GetLength();
unsigned char* lpBuf;
lpBuf = new unsigned char[nFileLen];
nFileLen = file.Read(lpBuf, nFileLen);
file.Close();
if (lLineBytes * lHeight < 4 * nFileLen)
{
// 提示用戶
MessageBox("載體位圖太小,不能容納水印!", "系統提示" , MB_ICONINFORMATION | MB_OK);
// 釋放內存
delete lpBuf;
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 填冗余位時的移位序列
int move1[13] = {6, 5, 2, 0, 7, 4, 2, 1, -2, 6, 4, 3, 0};
// 待隱藏文件的字節掩碼序列
unsigned char mask1[13]={192, 32, 28, 3, 128, 112, 12, 2, 1, 192, 48, 8, 7};
// 位圖文件的字節掩碼序列
unsigned char mask2[13]={252, 254, 248, 252, 254, 248, 252, 254, 251, 252, 252, 254, 248};
// 為1時pointer1指針加一
int add1[13]={0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1};
// 為1時pointer2指針加一
int add2[13]={1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
// 臨時指針
int pointer1 = 0;
int pointer2 = 0;
int pointer3 = 0;
while(pointer1 <= nFileLen)
{
// 將水印比特流嵌入到載體位圖
if (move1[pointer3] > 0)
*(lpDIBBits + pointer2) = (*(lpDIBBits + pointer2) & mask2[pointer3])|((lpBuf[pointer1] & mask1[pointer3]) >> move1[pointer3]);
else
*(lpDIBBits + pointer2) = (*(lpDIBBits + pointer2) & mask2[pointer3])|((lpBuf[pointer1] & mask1[pointer3]) << move1[pointer3] * (-1));
//修正指針
if (add1[pointer3] == 1)
pointer1++;
if (add2[pointer3] == 1)
pointer2++;
pointer3++;
pointer3 %= 13;
}
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
delete lpBuf;//釋放緩存
// 恢復光標
EndWaitCursor();
}
/*************************************************************************
*
* 函數名稱:
* Get()
*
* 參數:
* HDIB hDIB - 待處理的DIB
* CFile& file - 水印文件
*
* 返回值:
* void - 無返回值
*
* 說明:
* 該函數從DIB圖象提取出水印
*
************************************************************************/
void CWaterMarking::Get(HDIB hDIB, CFile &file)
{
// 嵌入水印的長度
int nFileLen = 54 + 3 * WIDTH * HEIGHT;
// 指向DIB的指針
LPBYTE lpDIB;
// 指向DIB象素指針
LPBYTE lpDIBBits;
// 鎖定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB圖像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判斷是否是24-bpp位圖
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用戶
MessageBox("請先將其轉換為24位色位圖,再進行處理!", "系統提示" , MB_ICONINFORMATION | MB_OK);
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光標形狀
BeginWaitCursor();
// DIB的寬度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 計算圖像每行的字節數
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 分配并初始化內存
unsigned char* lpBuf1;
unsigned char* lpBuf2;
lpBuf1 = new unsigned char [lLineBytes * lHeight];
lpBuf2 = new unsigned char [lLineBytes * lHeight];
memset(lpBuf1, 0, lLineBytes * lHeight);
memset(lpBuf2, 0, lLineBytes * lHeight);
//拼合文件信息字節時的移位序列
int move2[13] = {6, 5, 2, 0, 7, 4, 2, 1, -2, 6, 4, 3, 0};
//位圖文件字節的掩碼序列
unsigned char mask2[13]={3, 1, 7, 3, 1, 7, 3, 1, 4, 3, 3, 1, 7};
// 為1時pointer1指針加一
int add1[13]={0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1};
// 為1時pointer2指針加一
int add2[13]={1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
// 臨時指針
int pointer1 = 0;
int pointer2 = 0;
int pointer3 = 0;
int pointer4 = 0;
// 提取水印數據
while(true)
{
// 從DIB字節流中提取出水印數據
if(move2[pointer3] > 0)
lpBuf2[pointer1] |= (*(lpDIBBits + pointer2) & mask2[pointer3]) << move2[pointer3];
else
lpBuf2[pointer1] |= (*(lpDIBBits + pointer2) & mask2[pointer3]) >> (move2[pointer3] * (-1));
if(add1[pointer3] == 1)
{
lpBuf1[pointer4] = lpBuf2[pointer1];
pointer4++;
// 水印提取完畢,跳出循環
if(pointer4 > nFileLen)
break;
//修正指針
pointer1++;
}
//修正指針
if(add2[pointer3] == 1)
pointer2++;
pointer3++;
pointer3 %= 13;
}
file.Write(lpBuf1, nFileLen);
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
//釋放緩存
delete lpBuf1;
delete lpBuf2;
// 恢復光標
EndWaitCursor();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -