在一張圖片中隱藏另一張圖片


首先是在灰度圖中隱藏灰度圖

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

這里先得到兩張灰度圖

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

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM