首先是在灰度圖中隱藏灰度圖
因為是交作業嘛,為了簡單就依次在每個字節中隱藏信息,如果有什么不想讓人看見的東西要隱藏,可以自己有選擇性的隱藏
這里先得到兩張灰度圖


將第二幅圖片當作秘密圖片插入一圖,這里先將第二幅圖置亂

這里采用的是菱形置亂的方法,即在菱形中從第一行開始從左向右依次寫入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 }
