⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 embed.cpp

📁 一个实用的水印加密解密程序
💻 CPP
字号:
// 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("请打开文件!");
		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;
   //**********************************************************显示水印图像的位和长宽
   	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("水印图像过大,请更换较小的水印图像!","错误",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("请打开文件!");
		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填充的像素个数
		}
		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("请更换较小位数的水印图像");
		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;
	   //将水印图像灰度转换
	 	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,"未标题 bmp","未标题 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;//变换后的坐标

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];
	  
}	

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -