首先是在灰度图中隐藏灰度图
因为是交作业嘛,为了简单就依次在每个字节中隐藏信息,如果有什么不想让人看见的东西要隐藏,可以自己有选择性的隐藏
这里先得到两张灰度图


将第二幅图片当作秘密图片插入一图,这里先将第二幅图置乱

这里采用的是菱形置乱的方法,即在菱形中从第一行开始从左向右依次写入1到n,替换时从第一列从上到下依次读取序号,即第一列序号对应的像素作为第一个像素
代码如下,这里我用的算法比较笨就将就吧,恢复置乱时只需要更改其中一条代码,在代码中已说明
再说明一下,我是将菱形补全为正方形,用0填充,方法虽笨但是能用
/*
对图片进行置乱处理
2015年6月2日20:02:18
blog:http://www.cnblogs.com/wd1001/
*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
/*
位图头结构
*/
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER
{
unsigned char bfType[2];//文件格式
unsigned long bfSize;//文件大小
unsigned short bfReserved1;//保留
unsigned short bfReserved2;
unsigned long bfOffBits; //DIB数据在文件中的偏移量
}fileHeader;
#pragma pack()
/*
位图数据信息结构
*/
#pragma pack(1)
typedef struct tagBITMAPINFOHEADER
{
unsigned long biSize;//该结构的大小
long biWidth;//文件宽度
long biHeight;//文件高度
unsigned short biPlanes;//平面数
unsigned short biBitCount;//颜色位数
unsigned long biCompression;//压缩类型
unsigned long biSizeImage;//DIB数据区大小
long biXPixPerMeter;
long biYPixPerMeter;
unsigned long biClrUsed;//多少颜色索引表
unsigned long biClrImporant;//多少重要颜色
}fileInfo;
#pragma pack()
/*
调色板结构
*/
#pragma pack(1)
typedef struct tagRGBQUAD
{
unsigned char rgbBlue; //蓝色分量亮度
unsigned char rgbGreen;//绿色分量亮度
unsigned char rgbRed;//红色分量亮度
unsigned char rgbReserved;
}rgbq;
#pragma pack()
typedef struct MixSpace
{
unsigned long mix[600];
}MixS;
int main()
{
FILE * fpOri,* fpSec;
int i,j,k,t;
int m=1;
unsigned char ImgData[300][300];
unsigned char ImgData2[300][300];
/*这里采用菱形置乱*/
MixS * MixBox=(MixS *)malloc(sizeof(MixS)*600);//置乱模板
MixS * MixBox2=(MixS *)malloc(sizeof(MixS)*300);//置乱后模板
fileHeader * fh;
fileInfo * fi;
rgbq * fq;
if((fpOri=fopen("G:/vc6.0/work/3/31.bmp","rb"))==NULL)
{
printf("打开文件失败");
exit(0);
}
if((fpSec=fopen("G:/vc6.0/work/3/32.bmp","wb"))==NULL)
{
printf("创建文件失败");
exit(0);
}
fh=(fileHeader *)malloc(sizeof(fileHeader));
fi=(fileInfo *)malloc(sizeof(fileInfo));
fq=(rgbq *)malloc(sizeof(rgbq)*256);
fread(fh,sizeof(fileHeader),1,fpOri);
fread(fi,sizeof(fileInfo),1,fpOri);
fread(fq,sizeof(rgbq),256,fpOri);
for(i=0;i<fi->biHeight;i++)
{
for(j=0;j<(fi->biWidth+3)/4*4;j++)
fread(&ImgData[i][j],1,1,fpOri);
}
/*置乱模板初始化*/
for(i=0;i<(fi->biWidth+3)/4*4*2-1;i++)
{
if(i<(fi->biWidth+3)/4*4)
{
k=(fi->biWidth+3)/4*4-1-i;
t=i+1;
for(j=0;j<(fi->biWidth+3)/4*4*2-1;j++)
{
if(k>0)
{
(MixBox+i)->mix[j]=0;
k--;
}
else if(t>0)
{
(MixBox+i)->mix[j]=m;
(MixBox+i)->mix[j+1]=0;
j++;
m++;
t--;
}
else
(MixBox+i)->mix[j]=0;
}
}
else
{
k=i-(fi->biWidth+3)/4*4+1;
t=(fi->biWidth+3)/4*4-k;
for(j=0;j<(fi->biWidth+3)/4*4*2-1;j++)
{
if(k>0)
{
(MixBox+i)->mix[j]=0;
k--;
}
else if(t>0)
{
(MixBox+i)->mix[j]=m;
(MixBox+i)->mix[j+1]=0;
j++;
m++;
t--;
}
else
(MixBox+i)->mix[j]=0;
}
}
}
/*置乱后模板*/
k=t=0;
for(i=0;i<(fi->biWidth+3)/4*4*2-1;i++)
{
for(j=0;j<(fi->biWidth+3)/4*4*2-1;j++)
{
if(((MixBox+j)->mix[i])!=0)
{
(MixBox2+k)->mix[t]=(MixBox+j)->mix[i];
t++;
if(t>=(fi->biWidth+3)/4*4)
{
k++;
t=0;
}
}
}
}
/*将图片置乱*/
for(i=0;i<fi->biHeight;i++)
{
for(j=0;j<(fi->biWidth+3)/4*4;j++)
{
k=((MixBox2+i)->mix[j])/((fi->biWidth+3)/4*4);
t=((MixBox2+i)->mix[j])%((fi->biWidth+3)/4*4-1);
/*
恢复置乱时只需将这句改为
ImgData2[k][t]=ImgData[i][j];
并修改前面文件路径即可
*/
ImgData2[i][j]=ImgData[k][t];
}
}
/*将图片数据写入*/
fwrite(fh,sizeof(fileHeader),1,fpSec);
fwrite(fi,sizeof(fileInfo),1,fpSec);
fwrite(fq,sizeof(rgbq),256,fpSec);
for(i=0;i<fi->biHeight;i++)
{
for(j=0;j<(fi->biWidth+3)/4*4;j++)
fwrite(&ImgData2[i][j],1,1,fpSec);
}
free(fh);
free(fi);
free(fq);
free(MixBox);
free(MixBox2);
fclose(fpOri);
fclose(fpSec);
printf("success\n");
return 0;
}
好了下面就是隐藏后图片了,这里舍弃图片低四位,将秘密图片高四位隐藏到载体图低四位

载体图片改变有点大,可以考虑将图片隐藏在大一点图片中,一字节只隐藏2位或者1位,效果会更好
1 /*
2 将一张图片隐藏到另一张图片中
3 载体图为灰度图
4 blog:http://www.cnblogs.com/wd1001/
5 2015年6月3日17:59:34
6 */
7 #include<stdio.h>
8 #include<malloc.h>
9 #include<stdlib.h>
10 /*
11 位图头结构
12 */
13 #pragma pack(1)
14 typedef struct tagBITMAPFILEHEADER
15 {
16 unsigned char bfType[2];//文件格式
17 unsigned long bfSize;//文件大小
18 unsigned short bfReserved1;//保留
19 unsigned short bfReserved2;
20 unsigned long bfOffBits; //DIB数据在文件中的偏移量
21 }fileHeader;
22 #pragma pack()
23 /*
24 位图数据信息结构
25 */
26 #pragma pack(1)
27 typedef struct tagBITMAPINFOHEADER
28 {
29 unsigned long biSize;//该结构的大小
30 long biWidth;//文件宽度
31 long biHeight;//文件高度
32 unsigned short biPlanes;//平面数
33 unsigned short biBitCount;//颜色位数
34 unsigned long biCompression;//压缩类型
35 unsigned long biSizeImage;//DIB数据区大小
36 long biXPixPerMeter;
37 long biYPixPerMeter;
38 unsigned long biClrUsed;//多少颜色索引表
39 unsigned long biClrImporant;//多少重要颜色
40 }fileInfo;
41 #pragma pack()
42 /*
43 调色板结构
44 */
45 #pragma pack(1)
46 typedef struct tagRGBQUAD
47 {
48 unsigned char rgbBlue; //蓝色分量亮度
49 unsigned char rgbGreen;//绿色分量亮度
50 unsigned char rgbRed;//红色分量亮度
51 unsigned char rgbReserved;
52 }rgbq;
53 #pragma pack()
54
55 int main()
56 {
57 FILE * fpCov,* fpSec,*fpSte;
58 int i,j;
59 unsigned char ImgData[300][300];
60 unsigned char ImgData2[300][300];
61
62 fileHeader * fh,*fh2;
63 fileInfo * fi,*fi2;
64 rgbq * fq,*fq2;
65 if((fpCov=fopen("G:/vc6.0/work/3/21.bmp","rb"))==NULL)
66 {
67 printf("打开文件失败");
68 exit(0);
69 }
70
71 if((fpSec=fopen("G:/vc6.0/work/3/32.bmp","rb"))==NULL)
72 {
73 printf("打开文件失败");
74 exit(0);
75 }
76 if((fpSte=fopen("G:/vc6.0/work/3/123.bmp","wb"))==NULL)
77 {
78 printf("创建文件失败");
79 exit(0);
80 }
81 /*
82 读取载体图片
83 */
84 fh=(fileHeader *)malloc(sizeof(fileHeader));
85 fi=(fileInfo *)malloc(sizeof(fileInfo));
86 fq=(rgbq *)malloc(sizeof(rgbq)*256);
87 fread(fh,sizeof(fileHeader),1,fpCov);
88 fread(fi,sizeof(fileInfo),1,fpCov);
89 fread(fq,sizeof(rgbq),256,fpCov);
90
91 for(i=0;i<fi->biHeight;i++)
92 {
93 for(j=0;j<(fi->biWidth+3)/4*4;j++)
94 fread(&ImgData[i][j],1,1,fpCov);
95 }
96 /*读取秘密图片*/
97 fh2=(fileHeader *)malloc(sizeof(fileHeader));
98 fi2=(fileInfo *)malloc(sizeof(fileInfo));
99 fq2=(rgbq *)malloc(sizeof(rgbq)*256);
100 fread(fh2,sizeof(fileHeader),1,fpSec);
101 fread(fi2,sizeof(fileInfo),1,fpSec);
102 fread(fq2,sizeof(rgbq),256,fpSec);
103
104 for(i=0;i<fi->biHeight;i++)
105 {
106 for(j=0;j<(fi->biWidth+3)/4*4;j++)
107 fread(&ImgData2[i][j],1,1,fpSec);
108 }
109 /*隐藏图片*/
110 for(i=0;i<fi->biHeight;i++)
111 {
112 for(j=0;j<(fi->biWidth+3)/4*4;j++)
113 {
114 /*将载体图片低四位置零*/
115 ImgData[i][j]=ImgData[i][j]&240;
116 /*将秘密图片低四位置零*/
117 ImgData2[i][j]=ImgData2[i][j]&240;
118 /*将秘密图片高四位移到低四位*/
119 ImgData2[i][j]=ImgData2[i][j]>>4;
120 /*将秘密图片隐藏到载体图片中*/
121 ImgData[i][j]=ImgData[i][j]+ImgData2[i][j];
122 }
123 }
124 /*将图片数据写入*/
125 fwrite(fh,sizeof(fileHeader),1,fpSte);
126 fwrite(fi,sizeof(fileInfo),1,fpSte);
127 fwrite(fq,sizeof(rgbq),256,fpSte);
128 for(i=0;i<fi->biHeight;i++)
129 {
130 for(j=0;j<(fi->biWidth+3)/4*4;j++)
131 fwrite(&ImgData[i][j],1,1,fpSte);
132 }
133
134
135 free(fh);
136 free(fi);
137 free(fq);
138 fclose(fpCov);
139 fclose(fpSec);
140 fclose(fpSte);
141 printf("success\n");
142 return 0;
143 }
秘密图片的提取呢,也就非常简单了
提取并恢复置乱:


下面是提取秘密图片的代码,就不多做解释了,跟隐藏代码差不多
1 /*
2 从灰度图片中提取隐藏图片
3 2015年6月3日19:32:12
4 blog:http://www.cnblogs.com/wd1001/
5 */
6 #include<stdio.h>
7 #include<malloc.h>
8 #include<stdlib.h>
9 /*
10 位图头结构
11 */
12 #pragma pack(1)
13 typedef struct tagBITMAPFILEHEADER
14 {
15 unsigned char bfType[2];//文件格式
16 unsigned long bfSize;//文件大小
17 unsigned short bfReserved1;//保留
18 unsigned short bfReserved2;
19 unsigned long bfOffBits; //DIB数据在文件中的偏移量
20 }fileHeader;
21 #pragma pack()
22 /*
23 位图数据信息结构
24 */
25 #pragma pack(1)
26 typedef struct tagBITMAPINFOHEADER
27 {
28 unsigned long biSize;//该结构的大小
29 long biWidth;//文件宽度
30 long biHeight;//文件高度
31 unsigned short biPlanes;//平面数
32 unsigned short biBitCount;//颜色位数
33 unsigned long biCompression;//压缩类型
34 unsigned long biSizeImage;//DIB数据区大小
35 long biXPixPerMeter;
36 long biYPixPerMeter;
37 unsigned long biClrUsed;//多少颜色索引表
38 unsigned long biClrImporant;//多少重要颜色
39 }fileInfo;
40 #pragma pack()
41 /*
42 调色板结构
43 */
44 #pragma pack(1)
45 typedef struct tagRGBQUAD
46 {
47 unsigned char rgbBlue; //蓝色分量亮度
48 unsigned char rgbGreen;//绿色分量亮度
49 unsigned char rgbRed;//红色分量亮度
50 unsigned char rgbReserved;
51 }rgbq;
52 #pragma pack()
53
54 int main()
55 {
56 FILE * fpCov,* fpSec,*fpSte;
57 int i,j;
58 unsigned char ImgData[300][300];
59 unsigned char ImgData2[300][300];
60
61 fileHeader * fh;
62 fileInfo * fi;
63 rgbq * fq;
64 if((fpSte=fopen("G:/vc6.0/work/3/123.bmp","rb"))==NULL)
65 {
66 printf("打开文件失败");
67 exit(0);
68 }
69
70 if((fpCov=fopen("G:/vc6.0/work/3/123C.bmp","wb"))==NULL)
71 {
72 printf("创建文件失败");
73 exit(0);
74 }
75 if((fpSec=fopen("G:/vc6.0/work/3/123S.bmp","wb"))==NULL)
76 {
77 printf("创建文件失败");
78 exit(0);
79 }
80 /*
81 读取图片
82 */
83 fh=(fileHeader *)malloc(sizeof(fileHeader));
84 fi=(fileInfo *)malloc(sizeof(fileInfo));
85 fq=(rgbq *)malloc(sizeof(rgbq)*256);
86 fread(fh,sizeof(fileHeader),1,fpSte);
87 fread(fi,sizeof(fileInfo),1,fpSte);
88 fread(fq,sizeof(rgbq),256,fpSte);
89
90 for(i=0;i<fi->biHeight;i++)
91 {
92 for(j=0;j<(fi->biWidth+3)/4*4;j++)
93 fread(&ImgData[i][j],1,1,fpSte);
94 }
95
96 /*提取图片*/
97 for(i=0;i<fi->biHeight;i++)
98 {
99 for(j=0;j<(fi->biWidth+3)/4*4;j++)
100 {
101 /*提取低四位存到秘密图片中*/
102 ImgData2[i][j]=ImgData[i][j]&15;
103 /*将秘密图片低四位移到高四位*/
104 ImgData2[i][j]=ImgData2[i][j]<<4;
105 /*提取载体图片*/
106 ImgData[i][j]=ImgData[i][j]&240;
107 }
108 }
109 /*将载体图片数据写入*/
110 fwrite(fh,sizeof(fileHeader),1,fpCov);
111 fwrite(fi,sizeof(fileInfo),1,fpCov);
112 fwrite(fq,sizeof(rgbq),256,fpCov);
113 for(i=0;i<fi->biHeight;i++)
114 {
115 for(j=0;j<(fi->biWidth+3)/4*4;j++)
116 fwrite(&ImgData[i][j],1,1,fpCov);
117 }
118 /*将秘密图片数据写入*/
119 fwrite(fh,sizeof(fileHeader),1,fpSec);
120 fwrite(fi,sizeof(fileInfo),1,fpSec);
121 fwrite(fq,sizeof(rgbq),256,fpSec);
122 for(i=0;i<fi->biHeight;i++)
123 {
124 for(j=0;j<(fi->biWidth+3)/4*4;j++)
125 fwrite(&ImgData2[i][j],1,1,fpSec);
126 }
127
128 free(fh);
129 free(fi);
130 free(fq);
131 fclose(fpCov);
132 fclose(fpSec);
133 fclose(fpSte);
134 printf("success\n");
135 return 0;
136 }
在RGB图片中隐藏图片
到此这次作业也就完成了,下面是额外搞的一个在RGB图中隐藏灰度图,因为不是作业,也就没写提取代码
1 /*
2 将一张图片隐藏到另一张图片中
3 载体图为真彩图
4 blog:http://www.cnblogs.com/wd1001/
5 2015年6月5日16:06:16
6 */
7 #include<stdio.h>
8 #include<malloc.h>
9 #include<stdlib.h>
10 /*
11 位图头结构
12 */
13 #pragma pack(1)
14 typedef struct tagBITMAPFILEHEADER
15 {
16 unsigned char bfType[2];//文件格式
17 unsigned long bfSize;//文件大小
18 unsigned short bfReserved1;//保留
19 unsigned short bfReserved2;
20 unsigned long bfOffBits; //DIB数据在文件中的偏移量
21 }fileHeader;
22 #pragma pack()
23 /*
24 位图数据信息结构
25 */
26 #pragma pack(1)
27 typedef struct tagBITMAPINFOHEADER
28 {
29 unsigned long biSize;//该结构的大小
30 long biWidth;//文件宽度
31 long biHeight;//文件高度
32 unsigned short biPlanes;//平面数
33 unsigned short biBitCount;//颜色位数
34 unsigned long biCompression;//压缩类型
35 unsigned long biSizeImage;//DIB数据区大小
36 long biXPixPerMeter;
37 long biYPixPerMeter;
38 unsigned long biClrUsed;//多少颜色索引表
39 unsigned long biClrImporant;//多少重要颜色
40 }fileInfo;
41 #pragma pack()
42 /*
43 调色板结构
44 */
45 #pragma pack(1)
46 typedef struct tagRGBQUAD
47 {
48 unsigned char rgbBlue; //蓝色分量亮度
49 unsigned char rgbGreen;//绿色分量亮度
50 unsigned char rgbRed;//红色分量亮度
51 unsigned char rgbReserved;
52 }rgbq;
53 #pragma pack()
54
55 int main()
56 {
57 FILE * fpCov,* fpSec,*fpSte;
58 int i,j,k;
59 int h,m,l;//分别存储灰度图的高四位的2位、1位、1位
60 unsigned char ImgData[300][300][3];
61 unsigned char ImgData2[300][300];
62
63 fileHeader * fh,*fh2;
64 fileInfo * fi,*fi2;
65 rgbq * fq;
66 if((fpCov=fopen("G:/vc6.0/work/3/2.bmp","rb"))==NULL)
67 {
68 printf("打开文件失败");
69 exit(0);
70 }
71
72 if((fpSec=fopen("G:/vc6.0/work/3/32.bmp","rb"))==NULL)
73 {
74 printf("打开文件失败");
75 exit(0);
76 }
77 if((fpSte=fopen("G:/vc6.0/work/3/121.bmp","wb"))==NULL)
78 {
79 printf("创建文件失败");
80 exit(0);
81 }
82 /*
83 读取载体图片
84 */
85 fh=(fileHeader *)malloc(sizeof(fileHeader));
86 fi=(fileInfo *)malloc(sizeof(fileInfo));
87 fread(fh,sizeof(fileHeader),1,fpCov);
88 fread(fi,sizeof(fileInfo),1,fpCov);
89
90 for(i=0;i<fi->biHeight;i++)
91 {
92 for(j=0;j<(fi->biWidth+3)/4*4;j++)
93 { for(k=0;k<3;k++)
94 fread(&ImgData[i][j][k],1,1,fpCov);
95 }
96 }
97 /*读取秘密图片*/
98 fh2=(fileHeader *)malloc(sizeof(fileHeader));
99 fi2=(fileInfo *)malloc(sizeof(fileInfo));
100 fq=(rgbq *)malloc(sizeof(rgbq)*256);
101 fread(fh2,sizeof(fileHeader),1,fpSec);
102 fread(fi2,sizeof(fileInfo),1,fpSec);
103 fread(fq,sizeof(rgbq),256,fpSec);
104
105 for(i=0;i<fi->biHeight;i++)
106 {
107 for(j=0;j<(fi->biWidth+3)/4*4;j++)
108 fread(&ImgData2[i][j],1,1,fpSec);
109 }
110 /*隐藏图片*/
111 for(i=0;i<fi2->biHeight;i++)
112 {
113 for(j=0;j<(fi2->biWidth+3)/4*4;j++)
114 {
115 /*提取秘密图片高两位*/
116 h=ImgData2[i][j]&192;
117 h=h>>6;
118 /*提取秘密图片第6位*/
119 m=ImgData2[i][j]&32;
120 m=m>>5;
121 /*提取秘密图片第5位*/
122 l=ImgData2[i][j]&16;
123 l=l>>4;
124 for(k=0;k<3;k++)
125 {
126 /*将秘密图片高两位隐藏到底2位*/
127 if(k==0)
128 {
129 ImgData[i][j][k]=ImgData[i][j][k]&252;
130 ImgData[i][j][k]+=h;
131 }
132 /*将秘密图片第6位隐藏到底1位*/
133 else if(k==1)
134 {
135 ImgData[i][j][k]=ImgData[i][j][k]&254;
136 ImgData[i][j][k]+=m;
137 }
138 /*将秘密图片第6位隐藏到底1位*/
139 else
140 {
141 ImgData[i][j][k]=ImgData[i][j][k]&254;
142 ImgData[i][j][k]+=l;
143 }
144 }
145 }
146 }
147 /*将图片数据写入*/
148 fwrite(fh,sizeof(fileHeader),1,fpSte);
149 fwrite(fi,sizeof(fileInfo),1,fpSte);
150 for(i=0;i<fi->biHeight;i++)
151 {
152 for(j=0;j<(fi->biWidth+3)/4*4;j++)
153 for(k=0;k<3;k++)
154 fwrite(&ImgData[i][j][k],1,1,fpSte);
155 }
156
157
158 free(fh);
159 free(fi);
160 free(fq);
161 fclose(fpCov);
162 fclose(fpSec);
163 fclose(fpSte);
164 printf("success\n");
165 return 0;
166 }
来源:https://www.cnblogs.com/wd1001/p/4574209.html