//使用方法:
// BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]
//BmpSafe.exe /bmp2file (data BMP) [output file]
using System;
using System.IO;
using System.Drawing;
public class Bitmap24Writer
{
protected Bitmap bmp;
protected int curX, curY, iRGB;
protected uint bitsLeft, bitsTotal;
protected byte r, g, b;
public Bitmap24Writer(Bitmap bmp)
{
if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
throw new ArgumentException();
// assign vars
curX = curY = iRGB = 0;
this.bmp = bmp;
bitsLeft = bitsTotal = (uint)bmp.Height * (uint)bmp.Width * 3;
}
public uint GetUnusedBitCount()
{
return bitsLeft;
}
public uint GetMaxBitStorageCount()
{
return bitsTotal;
}
public Bitmap GetBitmap()
{
return bmp;
}
public bool WriteByte(byte by)
{
if (bitsLeft < 8)
return false;
uint bits2Do = 8;
for (; curX < bmp.Width; curX++)
{
if (curY >= bmp.Height)
curY = 0;
for (; curY < bmp.Height; curY++)
{
if (bits2Do == 0)
return true;
Color col = bmp.GetPixel(curX, curY);
r = col.R;
g = col.G;
b = col.B;
for ( ; ; )
{
byte curBit = (byte)(by & 1);
switch( iRGB )
{
case 0:
r = (byte)(r & 0xFE);
r |= curBit;
break;
case 1:
g = (byte)(g & 0xFE);
g |= curBit;
break;
case 2:
b = (byte)(b & 0xFE);
b |= curBit;
break;
}
--bits2Do;
--bitsLeft;
by >>= 1;
bmp.SetPixel(curX, curY, Color.FromArgb(r, g, b));
if (iRGB == 2)
{
iRGB = 0;
break;
}
iRGB++;
if (bits2Do == 0)
return true;
}
}
}
return true;
}
}
public class Bitmap24Reader
{
protected Bitmap bmp;
protected int curX, curY, iRGB;
protected uint bitsLeft, bitsTotal;
public Bitmap24Reader(Bitmap bmp)
{
if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
throw new ArgumentException();
curX = curY = iRGB = 0;
this.bmp = bmp;
bitsLeft = bitsTotal = (uint)bmp.Height * (uint)bmp.Width * 3;
}
public uint GetUnusedBitCount()
{
return bitsLeft;
}
public uint GetMaxBitStorageCount()
{
return bitsTotal;
}
public Bitmap GetBitmap()
{
return bmp;
}
public bool ReadByte(out byte by)
{
by = 0;
if (bitsLeft < 8)
return false;
byte bit = 0;
uint bits2Do = 8;
for (; curX < bmp.Width; curX++)
{
if (curY >= bmp.Height)
curY = 0;
for (; curY < bmp.Height; curY++)
{
if (bits2Do == 0)
return true;
Color col = bmp.GetPixel(curX, curY);
for ( ; ; )
{
switch( iRGB )
{
case 0:
bit = (byte)(col.R & 1);
break;
case 1:
bit = (byte)(col.G & 1);
break;
case 2:
bit = (byte)(col.B & 1);
break;
}
--bits2Do;
--bitsLeft;
by |= (byte)(bit << 7);
if (bits2Do != 0)
by >>= 1;
if (iRGB == 2)
{
iRGB = 0;
break;
}
iRGB++;
if (bits2Do == 0)
return true;
}
}
}
return true;
}
}
public class BitmapWorks
{
public static bool Data2Bmp(FileStream dataStream, FileStream bmpStream, string outFName, out string error)
{
error = "";
Bitmap bmp;
try
{
bmp = new Bitmap(bmpStream);
}
catch
{
error = "Are you sure the specified bitmap is a valid bitmap ?";
return false;
}
if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{
error = "Please drop only 24bit bitmaps,thanks !";
return false;
}
error += "-> Bitmap info: height=" + bmp.Height + " width=" + bmp.Width + "...\n";
if (dataStream.Length == 0)
{
error = "Input data has a not supported size of 0 !";
return false;
}
uint maxByteStorage = ((uint)bmp.Height * (uint)bmp.Width * 3) / 8;
error += "-> Up to " + (maxByteStorage-4) + " bytes could be stored in this bitmap...\n";
if (maxByteStorage < dataStream.Length + 4)
{
error = "Not enough pixel in target bitmap to hide the input data block !";
return false;
}
Bitmap24Writer bmpWriter = new Bitmap24Writer(bmp);
uint dataSize = (uint)dataStream.Length;
try
{
for (uint u = 0; u < 4; u++)
{
bmpWriter.WriteByte( (byte)dataSize );
dataSize >>= 8;
}
for (uint u = 0; u < dataStream.Length; u++)
bmpWriter.WriteByte( (byte)dataStream.ReadByte() );
}
catch
{
error = "Error while modifing the bitmap's pixels !";
return false;
}
double maxBitStorage = bmpWriter.GetMaxBitStorageCount();
double spaceUsed = (100 * (maxBitStorage - bmpWriter.GetUnusedBitCount())) / maxBitStorage;
error += "-> Space used: " + Convert.ToUInt32(spaceUsed) + "%...\n";
try
{
if ( File.Exists( outFName ) )
File.Delete( outFName );
bmpWriter.GetBitmap().Save(outFName);
}
catch
{
error = "Couldn't save output to " + outFName + " !";
return false;
}
error += "-> Output saved to: " + outFName + "...\n";
return true;
}
public static bool Bmp2Data(FileStream bmpStream, string outFName, out string error)
{
error = "";
Bitmap bmp;
try
{
bmp = new Bitmap(bmpStream);
}
catch
{
error = "Are you sure the specified bitmap is a valid bitmap ?";
return false;
}
Bitmap24Reader bmpReader;
try
{
bmpReader = new Bitmap24Reader(bmp);
}
catch (ArgumentException)
{
error = "This isn't a 24bit bitmap !";
return false;
}
FileStream outStream;
try
{
outStream = File.Create( outFName );
}
catch
{
error = "Couldn't create output file: " + outFName + " !";
return false;
}
uint dataSize = 0;
byte outByte;
try
{
for (uint u = 0; u < 4; u++)
{
if ( !bmpReader.ReadByte( out outByte ) )
throw new Exception();
dataSize |= (uint)( outByte << 8*3 );
if (u != 3)
dataSize >>= 8;
}
error += "-> Size of hidden data: " + dataSize + " bytes...\n";
for (uint u = 0; u < dataSize; u++)
{
if ( !bmpReader.ReadByte( out outByte ) )
throw new Exception();
outStream.WriteByte( outByte );
}
}
catch
{
error = "Exception caught while reading the hidden data !";
return false;
}
finally
{
outStream.Close();
}
error += "-> Output saved to: " + outFName + "...\n";
return true;
}
}
class BmpSafe
{
public static string cmdLine =
"Command line:\n" +
" BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]\n" +
" BmpSafe.exe /bmp2file (data BMP) [output file]";
private static string serviceOne = "/file2bmp";
private static string serviceTwo = "/bmp2file";
[STAThread]
static void Main(string[] args)
{
Console.WriteLine(
"BmpSafe - hide files in 24bit bitmaps\n" +
" a little steganografie implementation\n" +
" by yoda\n" +
"-------------------------------------------------------------------------------\n");
string inFile = "", inBmp, outFile;
bool bFile2Bmp;
if (args.Length < 2)
{
Console.WriteLine("!! Invalid number of arguments :(");
Console.WriteLine(cmdLine);
return; // ERR
}
if ( String.Compare(args[0], serviceOne, true) == 0 )
bFile2Bmp = true;
else if ( String.Compare(args[0], serviceTwo, true) == 0)
bFile2Bmp = false;
else
{
Console.WriteLine("!! First parameters must be either \"/file2bmp\" or \"/bmp2file\" !");
return;
}
inBmp = args[1];
if (bFile2Bmp)
{
if (args.Length < 3)
{
Console.WriteLine("!! Invalid number of arguments :(");
Console.WriteLine(cmdLine);
return;
}
inFile = args[2];
if (args.Length > 3)
outFile = args[3];
else
outFile = "Secret.BMP";
}
else
{
if (args.Length > 2)
outFile = args[2];
else
outFile = "Secret.bin";
}
Console.WriteLine("-> Processing input...");
try
{
string err;
bool ret;
if (bFile2Bmp)
ret = BitmapWorks.Data2Bmp(
File.OpenRead(inFile),
File.OpenRead(inBmp),
outFile,
out err );
else
ret = BitmapWorks.Bmp2Data(
File.OpenRead(inBmp),
outFile,
out err);
if (!ret)
{
Console.WriteLine("!! " + err);
return;
}
else
Console.Write( err );
}
catch(FileNotFoundException)
{
Console.WriteLine("!! At least one file could not be found :(");
return;
}
catch
{
Console.WriteLine("!! An exception occurred :(");
return;
}
Console.WriteLine("-> Job done...");
return;
}
}
分享到:
相关推荐
本项目聚焦于一个特定的实用程序——“C# pdf图幅统计小程序”,这是一个利用C#编写的软件,用于分析PDF文档中的图像数量,帮助用户快速了解PDF中的图像资源。 首先,我们要理解这个小程序的工作原理。PDF...
在C# WPF(Windows Presentation Foundation)开发中,有时我们需要将WPF应用程序中的视图或者控件导出为图片文件,以便于分享、保存或打印。这个任务可以通过编程实现,通常涉及以下几个关键知识点: 1. **绘图API...
在.NET框架中,C#是一种常用的编程...总的来说,C#实现的这个功能扩展了DataGridView的功能,让开发者能轻松地将用户界面的数据导出为Excel格式,同时保留了视觉元素,如图片,极大地提高了数据的可移植性和可处理性。
7. **保存数据**:如果需要保存查询结果,可以使用`DataTable.WriteXml()`方法将数据导出为XML文件,或者利用`System.IO`命名空间的类将数据写入文本文件或CSV文件。 8. **截图功能**:为了实现截图,可以使用`...
1. 可执行文件(EXE)结构:EXE文件是Windows操作系统中的应用程序载体,包含了程序的代码、数据和元信息。它的内部结构包括PE(Portable Executable)格式,由头文件、节区、导出和导入表、资源表等多个部分组成。 ...
通过这个实例,你将能够掌握C#中基本的图像加载、显示、绘制和保存技巧,并了解如何将这些技术应用于实际的Windows Forms应用程序中。这将是一个很好的起点,帮助你进一步探索更复杂的图像处理算法和应用。
标题中的“纯C#实现的mspaint增强版画图程序”指的是一个基于C#编程语言开发的图形编辑软件,它是对Windows系统自带的“画图”(mspaint)程序的一个功能增强版本。这个程序利用了.NET框架提供的WinForm技术以及GDI+...
本教程聚焦于C#中的图像处理技术,通过一个实际的“PDG格式图像处理实例教程”来深入理解这一主题。PDG格式是某些特定软件或系统中使用的图像文件格式,可能需要专门的库或工具进行读取和处理。 首先,我们要了解C#...
8. **与Visio的集成**:虽然我们使用C#和GDI+创建流程图,但也可以考虑与Visio进行交互,比如读取Visio的VSDX文件格式,将绘制的流程图导出为Visio兼容的格式,或者利用Visio的API来增强流程图的功能。 总结来说,...
7. **文件操作与存储**:如果工具提供保存颜色历史或导出颜色配置的功能,需要了解C#的文件操作,如`File.WriteAllText`用于写入文本文件。 8. **异常处理**:良好的异常处理机制可以确保程序在遇到错误时不会崩溃...
3. **绘制DataGridView**:为了在纸上重现`DataGridView`的内容,我们需要将控件转换为位图,然后在`PrintPage`事件中绘制这个位图。这通常涉及到一些尺寸计算,以确保在纸张上的比例正确。 ```csharp Bitmap ...
3. **格式支持**:QrCode.Net不仅支持常见的图像格式如PNG、JPG,还特别提到了能够将二维码导出为EPS(Encapsulated PostScript)格式,这在需要高质量印刷或专业设计的应用场景中非常有用。 4. **性能优势**:与...
在本文中,我们将深入探讨如何在C#中利用水晶报表(Crystal Reports)打印二维码和Code128条形码。这个示例项目“DemoQrCode”提供了完整的代码和资源,使得开发者可以直接运行并学习相关功能。 首先,让我们了解...
这个程序的主要功能是将文本字符转换成特定格式的位图,以便在液晶显示屏上清晰、高效地显示。下面将详细阐述液晶字模生成程序的相关知识点。 1. **液晶显示原理**: 液晶显示器利用液晶分子的光学性质来控制光线...
4. **图像保存与导出**: Bitmap类提供了Save()方法,可以将图像保存到文件,支持多种格式如JPEG、PNG、BMP等。 5. **图像缩放与旋转**: 使用Graphics对象的DrawImage()方法,配合适当的参数,可以实现图像的缩放、...
【标题】:“Flash雷达源程序”是一个基于Adobe Flash CS3开发的交互式应用程序,它被设计为一个可嵌入的控件,可以集成到其他Web页面或项目中,用于显示实时或模拟的雷达数据。这样的程序在教育、游戏、气象预报、...
标题"C_print_prview.zip_C#sato_sato_split_to_use"和描述"USB Print Preview to print on sato printer"暗示了这是一个关于使用C#编程语言处理SATO打印机的项目,特别是涉及打印预览功能。SATO打印机是工业标签和...