这次要在AVI文件中隐藏信息了,AVI文件是一系列的位图.

Steganography IV - Reading and Writing AVI files By Corinna John 
[读视频流]
Windows AVI 库是avifil32.dll中函数的集合. 使用之前先得用 AVIFileInit初始化. AVIFileOpen 打开文件, AVIFileGetStream 取得视频流. 这些函数申请的内存最后都必须释放. AVI文件可以包含四种不同类型的多个流,通常每种类型只有一个流,我们这里只关心视频流.

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//Initialize the AVI library
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern void AVIFileInit();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Open an AVI file
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll", PreserveSig=true)]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIFileOpen(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
ref int ppfile,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    String szFile,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int uMode,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int pclsidHandler);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Get a stream from an open AVI file
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIFileGetStream(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int pfile,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
out IntPtr ppavi,  
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int fccType,       
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int lParam);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Release an open AVI stream
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamRelease(IntPtr aviStream);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Release an ope AVI file
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIFileRelease(int pfile);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Close the AVI library
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern void AVIFileExit();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
private int aviFile = 0;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
private IntPtr aviStream;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
}

读帧之前,我们需要明了我们要读的东西: 第一个帧从哪里开始的?一共有多少帧?图像的高度宽度是多少?AVI库包含以下函数回答我们的上述问题

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//Get the start position of a stream
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll", PreserveSig=true)]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamStart(int pavi);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Get the length of a stream in frames
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll", PreserveSig=true)]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamLength(int pavi);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Get header information about an open stream
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamInfo(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int pAVIStream,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
ref AVISTREAMINFO psi,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int lSize);

调用以上函数我们可以填充位图信息头BITMAPINFOHEADER 结构,然后我们用以下函数来提取帧

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//Get a pointer to a GETFRAME object (returns 0 on error)
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamGetFrameOpen(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    IntPtr pAVIStream,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
ref BITMAPINFOHEADER bih);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Get a pointer to a packed DIB (returns 0 on error)
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamGetFrame(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int pGetFrameObj,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int lPos);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Release the GETFRAME object
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamGetFrameClose(int pGetFrameObj);

准备工作就绪,现在解压帧

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//get start position and count of frames
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
int firstFrame = AVIStreamStart(aviStream.ToInt32());
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
int countFrames = AVIStreamLength(aviStream.ToInt32());
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//get header information            
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
AVISTREAMINFO streamInfo = new AVISTREAMINFO();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息result 
= AVIStreamInfo(aviStream.ToInt32(), ref streamInfo,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    Marshal.SizeOf(streamInfo));
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//construct the expected bitmap header
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
BITMAPINFOHEADER bih = new BITMAPINFOHEADER();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息bih.biBitCount 
= 24;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息bih.biCompression 
= 0//BI_RGB;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
bih.biHeight = (Int32)streamInfo.rcFrame.bottom;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息bih.biWidth 
= (Int32)streamInfo.rcFrame.right;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息bih.biPlanes 
= 1;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息bih.biSize 
= (UInt32)Marshal.SizeOf(bih);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//prepare to decompress DIBs (device independend bitmaps)
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
int getFrameObject = AVIStreamGetFrameOpen(aviStream, ref bih);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Export the frame at the specified position
    }

然后保存为位图

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    //Create file header
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
    Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bfh.bfType 
= Avi.BMP_MAGIC_COOKIE;
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
//size of file as written to disk
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bfh.bfSize 
= (Int32)(55 + bih.biSizeImage);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bfh.bfOffBits 
= Marshal.SizeOf(bih) + Marshal.SizeOf(bfh);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
//Create or overwrite the destination file
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
    FileStream fs = new FileStream(dstFileName, System.IO.FileMode.Create);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    BinaryWriter bw 
= new BinaryWriter(fs);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
//Write header
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
    bw.Write(bfh.bfType);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bw.Write(bfh.bfSize);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bw.Write(bfh.bfReserved1);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bw.Write(bfh.bfReserved2);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bw.Write(bfh.bfOffBits);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
//Write bitmap info
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
    bw.Write(bitmapInfo);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
//Write bitmap data
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
    bw.Write(bitmapData);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    bw.Close();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    fs.Close();
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//end of ExportBitmap

应用程序会把解出来的位图当作普通位图来隐藏信息,如果载体文件是AVI文件,则提取第一帧到一个临时位图文件,放入一些信息,接下来是第二帧...最后一帧之后则关闭AVI文件,删除临时位图文件,接下来处理下一个载体文件.

[写视频流]
应用程序块打开AVI 载体文件时, 它创建另一个AVI文件来保存新的位图,新的文件大小和帧频率都与原来的一样, 我们不能用 Open() 来创建,而使用AVIFileCreateStream, AVIStreamSetFormat and AVIStreamWrite:

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//Create a new stream in an open AVI file
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIFileCreateStream(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
int pfile,
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
out IntPtr ppavi, 
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
ref AVISTREAMINFO ptr_streaminfo);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Set the format for a new stream
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamSetFormat(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    IntPtr aviStream, Int32 lPos, 
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    
ref BITMAPINFOHEADER lpFormat, Int32 cbFormat);
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
//Write a sample to a stream
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
[DllImport("avifil32.dll")]
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息
public static extern int AVIStreamWrite(
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    IntPtr aviStream, Int32 lStart, Int32 lSamples, 
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    IntPtr lpBuffer, Int32 cbBuffer, Int32 dwFlags, 
[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息    Int32 dummy1, Int32 dummy2);

现在创建视频流:

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//Create a new video stream
}

 写入帧:

[CodeProject每日一荐] 藏东西系列:在AVI文件中隐藏信息//Create an empty AVI file
}
[代码中CryptUtility类的改变]
HideOrExtract() 在前面的版本中一次读入所有载体位图,但现在必须改进了,每次加在一个位图,在加载下一个位图前先释放本位图.当前使用的位图(一个简单的位图或者AVI的一帧)保存在BitmapInfo结构中,通过by ref方式传递
}
MovePixelPosition需移到下一个载体位图时, 首先检查aviPosition. 如果aviPosition < 0, ,则保存位图且释放资源, 如果aviPosition >= 0, 则是AVI的一帧. 不保存为文件而是加到打开的AVI流中. 如果位图是简单位图或AVI的最后一帧, 该方法会移到下一个载体文件. 如果AVI中还有帧,则移到下一帧.

[使用代码]
工程中多了三个类
  • AviReader打开已有的AVI 文件复制帧到位图
  • AviWriter创建新的AVI 文件,组合帧到视频流中.
  • Avi包含函数声明和结构定义.
  • [注意]
    如果安装了VirtualDub,有可能设置为不允许其它程序写AVI的头,导致本程序无法正确运行

    相关文章:

    • 2021-08-06
    • 2021-06-24
    • 2021-06-19
    • 2021-10-03
    • 2021-10-15
    • 2022-01-23
    • 2021-04-15
    • 2021-11-27
    猜你喜欢
    • 2022-01-11
    • 2022-02-16
    • 2022-01-20
    • 2021-04-10
    • 2021-06-16
    • 2022-01-25
    • 2021-07-19
    相关资源
    相似解决方案