?? embed.cpp
字號(hào):
// Embed.cpp : implementation file
//
#include "stdafx.h"
#include "WaterMark.h"
#include "Embed.h"
#include "EncryptImage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEmbed dialog
CEmbed::CEmbed(CWnd* pParent /*=NULL*/)
: CDialog(CEmbed::IDD, pParent)
{
//{{AFX_DATA_INIT(CEmbed)
m_encrypt = -1;
//}}AFX_DATA_INIT
show[0]=show[1]=show[2]=FALSE;
m_hwnd[0]=m_hwnd[1]=m_hwnd[3]=NULL;
hSrcDC[0]=hSrcDC[1]=hSrcDC[2]=hDesDC[0]=hDesDC[1]=hDesDC[2]=NULL;
m_dib = new CDib();
m_dib1=new CDib();
ImageHeight=ImageWidth=0;
num=0;
flag=FALSE;
}
void CEmbed::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEmbed)
DDX_Radio(pDX, IDC_RADIO1, m_encrypt);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEmbed, CDialog)
//{{AFX_MSG_MAP(CEmbed)
ON_BN_CLICKED(IDC_BUTTON1, OnOpenImage)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON2, OnOpenWaterImage)
ON_BN_CLICKED(IDC_BUTTON4, OnClearAll)
ON_BN_CLICKED(IDC_BUTTON3, OnEmbedWaterImage)
ON_BN_CLICKED(IDC_BUTTON5, OnSaveWaterMarking)
ON_BN_CLICKED(IDC_RADIO1, OnSecret)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEmbed message handlers
void CEmbed::OnOpenImage()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(TRUE, "", NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, "(*.bmp)|*.bmp|所有文件(*.*)|*.*||",AfxGetMainWnd());
//讀取圖象的文件名CString Imagefilename;
if(dlg.DoModal()==IDOK)
{
//POSITION pos = dlg.GetStartPosition();
// ImageFilename = dlg.GetNextPathName(pos);
ImageFilename=dlg.GetPathName();
GetImageData();
if(m_hwnd[0]!=NULL)
m_hwnd[0]=NULL;
if(hSrcDC[0]!=NULL)
hSrcDC[0]=NULL;
if(hDesDC[0]!=NULL)
hDesDC[0]=NULL;
m_hwnd[0]=GetDlgItem(IDC_STATIC1);
hDesDC[0]=m_hwnd[0]->GetDC()->m_hDC;
hSrcDC[0]=CreateCompatibleDC(hDesDC[0]);
hBitmap[0]=(HBITMAP)LoadImage(AfxGetInstanceHandle(),ImageFilename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
GetObject(hBitmap[0],sizeof(BITMAP),&bm[0]);
SelectObject(hSrcDC[0],hBitmap[0]);
m_hwnd[0]->GetClientRect(&rect[0]);
::SetStretchBltMode(hDesDC[0],COLORONCOLOR);
::StretchBlt(hDesDC[0],rect[0].left,rect[0].top,rect[0].right,rect[0].bottom,hSrcDC[0],0,0,bm[0].bmWidth,bm[0].bmHeight,+SRCCOPY);
show[0]=TRUE;
SetTimer(NULL,50,0);
GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
//************************************************
CString s,s0,s1;
biBitCount=m_dib->GetBiBitCount();
m_edit1=new CEdit;
s.Format("%2d",ImageHeight);
s1.Format("%2d",ImageWidth);
s0.Format("%d",biBitCount);
str1="宿主圖象:"+s0+"位H×W:"+s+"X"+s1;
r.left=rect[0].right+20;
r.right=r.left+200;
r.top=rect[0].bottom+30;
r.bottom=r.top+20;
ShowText(str1,r,m_edit1);
}
}
void CEmbed::GetImageData()
{
int i,j;
if(m_ImageData !=NULL)
for(i=0; i<ImageHeight; i++)
delete [] m_ImageData[i];
if(ImageFilename.GetLength()==0)
{
MessageBox("請(qǐng)打開文件!");
return ;
}
m_dib->Open(ImageFilename);
ImageWidth = m_dib->GetWidth();
ImageHeight = m_dib->GetHeight();
biBitCount = m_dib->GetBiBitCount();
BYTE *Imagedata;
Imagedata =(BYTE *) m_dib->m_pDibBits;
int byteBitCount=m_dib->GetBiBitCount()/8;
m_ImageData =new RGBQUAD*[ImageHeight];
for (int m=0;m<ImageHeight;m++)
m_ImageData[m]=new RGBQUAD [ImageWidth];
int count = 0;
int num = 0;
for(i=ImageHeight-1; i>=0; i--)
{
for(j=0; j<ImageWidth; j++)
{
m_ImageData[i][j].rgbBlue=Imagedata[count++];
m_ImageData[i][j].rgbGreen=Imagedata[count++];
m_ImageData[i][j].rgbRed=Imagedata[count++];
m_ImageData[i][j].rgbReserved=0;
count += byteBitCount-3;
num+=1;
}
count += (4-(ImageWidth*byteBitCount)%4)%4;
}
}
void CEmbed::OnOpenWaterImage()
{
// TODO: Add your control notification handler code here
CFileDialog dlg1(TRUE, "", NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, "(*.bmp)|*.bmp|所有文件(*.*)|*.*||",AfxGetMainWnd());
//讀取圖象的文件名CString Imagefilename;
if(dlg1.DoModal()==IDOK)
{
if(m_hwnd[1]!=NULL)
m_hwnd[1]=NULL;
if(hSrcDC[1]!=NULL)
hSrcDC[1]=NULL;
if(hDesDC[1]!=NULL)
hDesDC[1]=NULL;
m_hwnd[1]=GetDlgItem(IDC_STATIC2);
hDesDC[1]=m_hwnd[1]->GetDC()->m_hDC;
hSrcDC[1]=CreateCompatibleDC(hDesDC[1]);
WaterImageFilename=dlg1.GetPathName();
hBitmap[1]=(HBITMAP)LoadImage(AfxGetInstanceHandle(),WaterImageFilename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
GetObject(hBitmap[1],sizeof(BITMAP),&bm[1]);
SelectObject(hSrcDC[1],hBitmap[1]);
m_hwnd[1]->GetClientRect(&rect[1]);
::SetStretchBltMode(hDesDC[1],COLORONCOLOR);
::StretchBlt(hDesDC[1],rect[1].left,rect[1].top,rect[1].right,rect[1].bottom,hSrcDC[1],0,0,bm[1].bmWidth,bm[1].bmHeight,+SRCCOPY);
show[1]=TRUE;
//**********************************************************顯示水印圖像的位和長(zhǎng)寬
CString s,s0,s1;
m_edit2=new CEdit;
s.Format("%2d",bm[1].bmHeight);
s1.Format("%2d",bm[1].bmWidth);
s0.Format("%d",bm[1].bmBitsPixel);
str2="水印圖象:"+s0+"位H×W:"+s+"X"+s1;
r1.left=rect[0].right+18;
r1.right=r.left+200;
r1.top=r.bottom+10;
r1.bottom=r1.top+20;
ShowText(str2,r1,m_edit2);
//****************************************
SetTimer(NULL,50,0);
if(hDesDC[0]!=NULL)
{
if(bm[0].bmHeight<bm[1].bmHeight||bm[0].bmWidth<bm[1].bmWidth)
{
MessageBox("水印圖像過大,請(qǐng)更換較小的水印圖像!","錯(cuò)誤",MB_OK);
}
else
{
// POSITION pos = dlg1.GetStartPosition();
// WaterImageFilename = dlg1.GetNextPathName(pos);
GetWaterImageData();
GetDlgItem(IDC_BUTTON3)->EnableWindow(TRUE);
}
}
}
}
void CEmbed::GetWaterImageData()
{
int i,j;
if(m_WaterImageData !=NULL)
for(i=0; i<WaterImageHeight; i++)
delete [] m_WaterImageData[i];
if(WaterImageFilename.GetLength()==0)
{
MessageBox("請(qǐng)打開文件!");
return ;
}
m_dib1->Open(WaterImageFilename);
WaterImageWidth = m_dib1->GetWidth();
WaterImageHeight = m_dib1->GetHeight();
biBitCount1 = m_dib1->GetBiBitCount();
BYTE *WaterImagedata;
WaterImagedata =(BYTE *) m_dib1->m_pDibBits;
int byteBitCount=m_dib1->GetBiBitCount()/8;
m_WaterImageData =new RGBQUAD*[WaterImageHeight];
for (int m=0;m<WaterImageHeight;m++)
m_WaterImageData[m]=new RGBQUAD [WaterImageWidth];
int count = 0;
for(i=WaterImageHeight-1; i>=0; i--)
{
for(j=0; j<WaterImageWidth; j++)
{
m_WaterImageData[i][j].rgbBlue=WaterImagedata[count++];
m_WaterImageData[i][j].rgbGreen=WaterImagedata[count++];
m_WaterImageData[i][j].rgbRed=WaterImagedata[count++];
m_WaterImageData[i][j].rgbReserved=0;
count += byteBitCount-3;
num+=1;//記錄沒有被0填充的像素個(gè)數(shù)
}
count += (4-(WaterImageWidth*byteBitCount)%4)%4;
}
}
void CEmbed::ShowText(CString s,RECT re,CEdit *edit)
{
edit=new CEdit;
edit->Create(ES_CENTER|WS_VISIBLE|ES_READONLY,re,this,1);
CFont *m_font=new CFont;
m_font->CreateFont(14,0,0,0,FW_SEMIBOLD,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH&FF_SWISS,"Arial");
edit->SetFont(m_font,TRUE);
edit->SetWindowText(s);
}
void CEmbed::OnClearAll()
{
// TODO: Add your control notification handler code here
ImageHeight=ImageWidth=biBitCount=0;
bm[1].bmHeight=bm[1].bmWidth=bm[1].bmBitsPixel=0;
str1="宿主圖象:0位H×W:0X0";
str2="水印圖像:0位H×W:0X0";
ShowText(str1,r,m_edit2);
ShowText(str2,r1,m_edit2);
hDesDC[0]=NULL;
hDesDC[1]=NULL;
::DeleteObject(hDesDC[0]);
::DeleteObject(hDesDC[1]);
a11=0;
a12=0;
a21=0;
a22=0;
T=0;
N=0;
flag=FALSE;
m_encrypt=-1;
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON5)->EnableWindow(FALSE);
UpdateData(FALSE);
Invalidate();
}
void CEmbed::OnEmbedWaterImage()
{
// TODO: Add your control notification handler code here
if(biBitCount<biBitCount1)
{
MessageBox("請(qǐng)更換較小位數(shù)的水印圖像");
return;
}
RGBQUAD *WaterCopyData;//copy waterimagedata to this arry;
WaterCopyData=new RGBQUAD [WaterImageHeight*WaterImageWidth];
int i,j;
BYTE r,g,b;
m_WaterEmbedData=new RGBQUAD*[ImageHeight];
for(int n=0;n<ImageHeight;n++)
m_WaterEmbedData[n]=new RGBQUAD [ImageWidth];
for(i=0;i<ImageHeight;i++)
for(j=0;j<ImageWidth;j++)
m_WaterEmbedData[i][j]=m_ImageData[i][j];
if(flag==TRUE)
{
Encrypt();
}
for(i=0;i<WaterImageHeight;i++)
for(j=0;j<WaterImageWidth;j++)
WaterCopyData[WaterImageHeight*i+j]=m_WaterImageData[i][j];
for(i=0;i<WaterImageHeight;i++)
for(j=0;j<WaterImageWidth;j++)
{
r=m_WaterEmbedData[i][j].rgbRed;
b=m_WaterEmbedData[i][j].rgbBlue;
g=m_WaterEmbedData[i][j].rgbGreen;
//將水印圖像灰度轉(zhuǎn)換
BYTE Gray=WaterCopyData[i*WaterImageHeight+j].rgbGreen;
//BYTE Gray=(BYTE)(0.11*WaterCopyData[i*WaterImageHeight+j].rgbRed+0.59*WaterCopyData[i*WaterImageHeight+j].rgbGreen+0.3*WaterCopyData[i*WaterImageHeight+j].rgbBlue);
LSB_watermarking(i,j,r,b,Gray);
}
CDC *dc=GetDC();
//水印圖像輸出定位
m_hwnd[2]=GetDlgItem(IDC_STATIC3);
m_hwnd[2]->GetClientRect(&rect[2]);
int StartX=rect[2].left+10;
int StartY=233;
float p,q;//縮放比例
if(rect[2].right<ImageWidth&&rect[2].bottom<ImageHeight)
{
p=(float)rect[2].right/ImageWidth;
q=(float)rect[2].bottom/ImageHeight;
}
else
q=p=1;
//MessageBox("Error!");
SetImagePixel(dc,StartX,StartY,ImageHeight,ImageWidth,m_WaterEmbedData,p,q);
GetDlgItem(IDC_BUTTON5)->EnableWindow(TRUE);
delete [] WaterCopyData;
ReleaseDC(dc);
}
void CEmbed::LSB_watermarking(int i,int j,BYTE a,BYTE b,BYTE c)
{
BYTE value=240;//1111 0000
BYTE bit[8],bit_value[4],hight,low,d;
d=c;
bit_value[0]=1;
bit_value[1]=2;
bit_value[2]=4;
bit_value[3]=8;
for(int m=0;m<8;m++)//將C的8位分離
{
bit[m]=c&1;
c>>=1;
}
low=bit[0]*bit_value[0]+bit[1]*bit_value[1]+bit[2]*bit_value[2]+bit[3]*bit_value[3];
hight=bit[4]*bit_value[0]+bit[5]*bit_value[1]+bit[6]*bit_value[2]+bit[7]*bit_value[3];
a=a&value;
a+=hight;
b=b&value;
b+=low;
m_WaterEmbedData[i][j].rgbRed=a;
m_WaterEmbedData[i][j].rgbBlue=b;
m_WaterEmbedData[i][j].rgbGreen=d;
}
void CEmbed:: SetImagePixel(CDC *pdc,int x_start,int y_start,int height,int width,RGBQUAD **m_imagedata,float a,float b)
{
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
pdc->SetPixel(x_start+(int)(j*a),y_start+(int)(i*b),RGB(m_imagedata[i][j].rgbRed,m_imagedata[i][j].rgbGreen,m_imagedata[i][j].rgbBlue));
}
void CEmbed::OnSaveWaterMarking()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(FALSE,"未標(biāo)題 bmp","未標(biāo)題 bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"位圖文件(*.bmp)|*.bmp");
if(dlg.DoModal()==IDOK)
{
CDib *m_saveDib;
m_saveDib=new CDib;
m_saveDib=m_dib;
// int byteBitCount=3;
int byteBitCount=m_dib->GetBiBitCount()/8;
long Hei=m_saveDib->GetHeight();
long Wid=m_saveDib->GetWidth();
int c=0;
for(int i=Hei-1;i>=0;i--)
{
for(int j=0;j<Wid;j++)
{
((BYTE *)m_saveDib->m_pDibBits)[c++]=m_WaterEmbedData[i][j].rgbBlue;
((BYTE *)m_saveDib->m_pDibBits)[c++]=m_WaterEmbedData[i][j].rgbGreen;
((BYTE *)m_saveDib->m_pDibBits)[c++]=m_WaterEmbedData[i][j].rgbRed;
c+=byteBitCount-3;
}
c+=(4-(Wid*byteBitCount)%4)%4;
}
CString savename;
savename=dlg.GetPathName();
m_saveDib->Save(savename);
}
return;
}
void CEmbed::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (show[0])
{
::StretchBlt(hDesDC[0], rect[0].left, rect[0].top, rect[0].right, \
rect[0].bottom, hSrcDC[0], 0, 0, bm[0].bmWidth, bm[0].bmHeight,+SRCCOPY);
}
if (show[1])
{
::StretchBlt(hDesDC[1], rect[1].left, rect[1].top, rect[1].right, \
rect[1].bottom, hSrcDC[1], 0, 0, bm[1].bmWidth, bm[1].bmHeight,+SRCCOPY);
}
if(show[2])
{
::StretchBlt(hDesDC[2], rect[2].left, rect[2].top, rect[2].right, \
rect[2].bottom, hSrcDC[2], 0, 0, bm[2].bmWidth, bm[2].bmHeight,+SRCCOPY);
}
CDialog::OnTimer(nIDEvent);
}
void CEmbed::OnSecret()
{
// TODO: Add your control notification handler code here
CEncryptImage m_encrypt;
m_encrypt.DoModal();
a11=m_encrypt.m_a11;
a12=m_encrypt.m_a12;
a21=m_encrypt.m_a21;
a22=m_encrypt.m_a22;
T=m_encrypt.m_zhouqi;
N=m_encrypt.m_number;
flag=TRUE;
}
void CEmbed::Encrypt()
{
int M;//mod M and M is small
int x1,y1;//變換后的坐標(biāo)
if(WaterImageHeight>WaterImageWidth)
M=WaterImageWidth;
else
M=WaterImageHeight;
m_WaterEncryptData=new RGBQUAD*[M];
for(int n=0;n<M;n++)
m_WaterEncryptData[n]=new RGBQUAD [M];
for(int i=0;i<N;i++)
{
for(int x=0;x<M;x++)
for(int y=0;y<M;y++)
{
x1=a11*x+a12*y;
y1=a21*x+a22*y;
x1=x1%M;
y1=y1%M;
// if(x1==0)
// x1=M-1;
// if(y1==0)
// y1=M-1;
m_WaterEncryptData[x1][y1].rgbReserved=0;
m_WaterEncryptData[x1][y1].rgbGreen=m_WaterImageData[x][y].rgbGreen;
m_WaterEncryptData[x1][y1].rgbRed=m_WaterImageData[x][y].rgbRed;
m_WaterEncryptData[x1][y1].rgbBlue=m_WaterImageData[x][y].rgbBlue;
}
for(int a=0;a<M;a++)
for(int b=0;b<M;b++)
m_WaterImageData[a][b]=m_WaterEncryptData[a][b];
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -