?? dib.cpp
字號:
// Dib.cpp : implementation file
//
#include "stdafx.h"
#include "圖像水印.h"
#include "Dib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDib
//IMPLEMENT_DYNCREATE(CDib, CView)
CDib::CDib()
{
m_pDib = NULL;
m_pWordData = NULL;
m_pFile = NULL;
m_pOldDibShow = NULL;
}
CDib::~CDib()
{
if( m_pDib != NULL )
delete [] m_pDib;
if( m_pWordData != NULL )
delete [] m_pWordData;
if (m_pFile != NULL)
delete [] m_pFile;
if (m_pOldDibShow != NULL)
delete [] m_pOldDibShow;
}
BEGIN_MESSAGE_MAP(CDib, CView)
//{{AFX_MSG_MAP(CDib)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDib drawing
void CDib::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CDib diagnostics
#ifdef _DEBUG
void CDib::AssertValid() const
{
CView::AssertValid();
}
void CDib::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDib message handlers
BOOL CDib::Load( const char *pszFilename )
{
CFile cf;
if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );
DWORD dwDibSize;
dwDibSize =
cf.GetLength() - sizeof( BITMAPFILEHEADER );
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
return( FALSE );
BITMAPFILEHEADER BFH;
try{
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||
BFH.bfType != 'MB' ||
cf.Read( pDib, dwDibSize ) != dwDibSize ){
delete [] pDib;
return( FALSE );
}
}
catch( CFileException *e ){
e->Delete();
delete [] pDib;
return( FALSE );
}
cf.Close();
if( m_pDib != NULL )
delete m_pDib;
if (BFH.bfReserved1 != 0) //含有隱藏信息,保存其大小
{
if (BFH.bfReserved2 == 0)
embfile_size = BFH.bfReserved1;
else
embfile_size = BFH.bfReserved1 + 65535;
}
m_pDib = pDib;
m_dwDibSize = dwDibSize;
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =
(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;
m_pDibBits =
&m_pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
if( m_nPaletteEntries != 0 ){
LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];
if( pLogPal != NULL ){
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;
for( int i=0; i<m_nPaletteEntries; i++ ){
pLogPal->palPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}
m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}
m_BitCount = 24; //24位位圖
p = m_pDibBits; //指向位圖數據的指針,用來執行處理操作用
bitmap_size = m_dwDibSize - (m_pDibBits - m_pDib);//真正的位圖數據的大小(即除頭結構外)
tag = BFH.bfReserved1;
return( TRUE );
}
BOOL CDib::Save( const char *pszFilename ) //保存含有隱藏信息的bmp
{
if( m_pDib == NULL )
return( FALSE );
CFile cf;
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );
try{
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );
if (embfile_size <= 65535) //由于bfReserved1是unsigned short型的,大小可能不能滿足要求,可能要用到reserved2
BFH.bfReserved1 = embfile_size;
else
{
BFH.bfReserved1 = embfile_size - 65535;
BFH.bfReserved2 = 1; //標記
}
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pDib, m_dwDibSize );
}
catch( CFileException *e ){
e->Delete();
return( FALSE );
}
return( TRUE );
}
BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style )
{
if( m_pDib == NULL )
return( FALSE );
long vWidth = m_pBIH->biWidth;
if( nWidth == -1 )
nWidth = m_pBIH->biWidth;
if( nHeight == -1 )
nHeight = m_pBIH->biHeight;
if (Style)
{
StretchDIBits( pDC->m_hDC, nX, nY,
nWidth, nHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY );
}
else
{
SetDIBitsToDevice( pDC->m_hDC, nX, nY,
m_pBIH->biWidth, m_pBIH->biHeight,
0, 0,
0, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB);
}
return( TRUE );
}
BOOL CDib::LoadEmbFile(const char * pszFilename)
{
CFile cf;
if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );
DWORD dwFileSize;
dwFileSize = cf.GetLength();
embfile_size = dwFileSize;
unsigned char *pFile;
pFile = new unsigned char [dwFileSize];
cf.Read( pFile, dwFileSize ); //將文件中內容讀入數組,解下來就開始嵌入操作
m_pFile = pFile;
q = pFile; //記錄下位置
return true;
}
void CDib::Embed()//嵌入
{
unsigned char bmdata;//bitmap data
unsigned char efdata;//embeddedfile data
int t = 7;
int x[8];
int s[8];
int last_bit; //記錄字節最低位本來的bit
for(UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
{
bmdata = *p;
for (int j = 0; j <= 7; j++) //計算各bit位
{
x[j] = bmdata & 1;
bmdata >>= 1;
}
last_bit = x[0];
x[0] = x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
if (t == 7) //宿主圖片每走過八個字節,計算一次s[]
{
efdata = *q;
for (j = 0; j <= 7; j++)
{
s[j] = efdata & 1;
efdata >>= 1;
}
}
x[0] ^= s[t];//隱藏信息
if (last_bit == 0) //嵌入隱藏信息
{
*p |= x[0];
}
else
{
*p &= 254 + x[0];
}
p++;
t--;
if (t == -1) //需要計算一次s[]
{
t = 7;
q++;
i2++;
}
}
}
void CDib::Pick()//提取
{
m_pFile = new unsigned char [embfile_size];
unsigned char *q = m_pFile;
unsigned char bmdata;//bitmap data
int x[8];
int s[8];
int t = 7;
for (UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)
{
bmdata = *p;
for (int j = 0; j <= 7; j++) //計算各bit位
{
x[j] = bmdata & 1;
bmdata >>= 1;
}
s[t] = x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
t--;
if (t == -1) //s[7]到s[0]組成一個字節
{
*q = s[7] * 128 + s[6] * 64 + s[5] * 32 + s[4] * 16 +
s[3] * 8 + s[2] * 4 + s[1] * 2 + s[0];
t = 7;
i2++;
q++;
}
p++;
}
}
void CDib::SavePicked( const char *pszFilename )
{
CFile cf;
cf.Open( pszFilename, CFile::modeCreate | CFile::modeWrite );
cf.Write( m_pFile, embfile_size );
}
void CDib::BackUpDib()
{
m_pOldDibShow = new unsigned char [bitmap_size];
::CopyMemory(m_pOldDibShow, m_pDibBits, bitmap_size); //將原始的數據單獨保存以便對比顯示
}
BOOL CDib::DrawContrast(CDC *pDC, int rect_width, int rect_height)
{ //看原圖,如果容納得下兩個圖,則不要壓縮,否則要壓縮
if (m_pOldDibShow == NULL)
return FALSE;
if (rect_width >= 2*m_pBIH->biWidth + 30 && rect_height >= m_pBIH->biHeight)
{
StretchDIBits( pDC->m_hDC, 0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pOldDibShow,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY ); // 原圖
StretchDIBits( pDC->m_hDC, m_pBIH->biWidth+30, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY ); // 嵌入隱藏信息的圖
}
else
{
int scale_i = m_pBIH->biWidth * 5 / (rect_width*2);
int scale_j = m_pBIH->biHeight / rect_height;
if (scale_i < scale_j)
scale_i = scale_j;
StretchDIBits( pDC->m_hDC, 0, 0,
m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pOldDibShow,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY ); // 原圖
StretchDIBits( pDC->m_hDC, m_pBIH->biWidth / scale_i+30, 0,
m_pBIH->biWidth / scale_i, m_pBIH->biHeight / scale_i,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY ); // 嵌入隱藏信息的圖
}
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -