C#合并BitMap图像生成超 * itmap
作者:记住我Gxy 时间:2023-12-08 18:24:11
当只需要两个图像合并的时候,可以简单的使用gdi+,把两个图像画到一个画布上面实现合并bitmap.
当需要将许多bitmap合并时,由于bitmap类限制,长度或宽度太大时会报异常,前面这种方法就行不通了。
由于bitmapp属于位图格式,了解图像格式后,发现,bitmap文件的第3-8位存储了文件大小信息,第19-22位存储了高度信息,第23-26位存储了宽度信息。文件头后面都是像素的argb,并无其它信息。于是,试想一下,如果把第二张图像的像素argb放到第一张后面,并修改第一张的文件头信息,是不是就可以实现文件合并了呢。事实证明:yes。
//设置文件头里面文件大小信息
public void SetBitmapFileSizeInfo(string filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
long le = fileInfo.Length;
string hexSize = le.ToString("X").PadLeft(8, '0');
int size1 = Convert.ToInt32(hexSize.Substring(0, 2), 16);
int size2 = Convert.ToInt32(hexSize.Substring(2, 2), 16);
int size3 = Convert.ToInt32(hexSize.Substring(4, 2), 16);
int size4 = Convert.ToInt32(hexSize.Substring(6, 2), 16);
byte[] sizeBytes = new byte[] { (byte)size4, (byte)size3, (byte)size2, (byte)size1 };
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write))
{
using (BinaryWriter r = new BinaryWriter(fs))
{
r.Seek(2, 0);
r.Write(sizeBytes, 0, sizeBytes.Length);
}
}
}
设置文件头里面文件长度和宽度信息
public void SetBitmapSizeInfo(string filePath,int width=0,int height=0)
{
if (height != 0)
{
string hexHeight = height.ToString("X").PadLeft(8, '0');
int h1 = Convert.ToInt32(hexHeight.Substring(0, 2), 16);
int h2 = Convert.ToInt32(hexHeight.Substring(2, 2), 16);
int h3 = Convert.ToInt32(hexHeight.Substring(4, 2), 16);
int h4 = Convert.ToInt32(hexHeight.Substring(6, 2), 16);
byte[] sizeHeight = new byte[] { (byte)h4, (byte)h3, (byte)h2, (byte)h1 };
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (BinaryWriter r = new BinaryWriter(fs))
{
r.Seek(22, 0);//高度保存位置
r.Write(sizeHeight, 0, sizeHeight.Length);
}
}
}
if (width != 0)
{
string hexWidth = height.ToString("X").PadLeft(8, '0');
int w1 = Convert.ToInt32(hexWidth.Substring(0, 2), 16);
int w2 = Convert.ToInt32(hexWidth.Substring(2, 2), 16);
int w3 = Convert.ToInt32(hexWidth.Substring(4, 2), 16);
int w4 = Convert.ToInt32(hexWidth.Substring(6, 2), 16);
byte[] sizeWidth = new byte[] { (byte)w4, (byte)w3, (byte)w2, (byte)w1 };
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
{
using (BinaryWriter r = new BinaryWriter(fs))
{
r.Seek(18, 0);//高度保存位置
r.Write(sizeWidth, 0, sizeWidth.Length);
}
}
}
}
合并多个bitmap文件,并生成一个最终文件
private void CreateBitMap(string tempPath,string imagePath)
{
string[] files = Directory.GetFiles(tempPath, "*.png");
Bitmap bmp;
int height=0;
for (int i = files.Length-1; i >0; i--)
{
string fileName = files[i];
bmp = new Bitmap(fileName);
if (i == files.Length - 1)
{
bmp.Save(imagePath, ImageFormat.Bmp);
height += bmp.Height;
bmp.Dispose();
continue;
}
else
{
byte[] bytes = GetImageRasterBytes(bmp, PixelFormat.Format32bppRgb);
using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Write))
{
fs.Seek(fs.Length, 0);
fs.Write(bytes, 0, bytes.Length);
}
height += bmp.Height;
bmp.Dispose();
}
}
SetBitmapFileSizeInfo(imagePath);
SetBitmapSizeInfo(imagePath, height: height);
//MessageBox.Show("合并成功");
}
private static byte[] GetImageRasterBytes(Bitmap bmp, PixelFormat format)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
byte[] bits = null;
try
{
// Lock the managed memory
BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);
// Declare an array to hold the bytes of the bitmap.
bits = new byte[bmpdata.Stride * bmpdata.Height];
// Copy the values into the array.
System.Runtime.InteropServices.Marshal.Copy(bmpdata.Scan0, bits, 0, bits.Length);
// Release managed memory
bmp.UnlockBits(bmpdata);
}
catch
{
return null;
}
return bits;
}
来源:https://blog.csdn.net/qq_35669328/article/details/100696671
标签:C#,合并,BitMap
0
投稿
猜你喜欢
Android自定义控件实现UC浏览器语音搜索效果
2022-06-01 06:59:40
Android 文件读写操作方法总结
2023-12-22 22:52:29
Android Init进程对信号的处理流程详细介绍
2022-10-25 18:03:31
java异常(Exception)处理机制详解
2023-06-06 08:21:48
C#操作DataGridView获取或设置当前单元格的内容
2022-04-01 14:44:25
IDEA 使用mybatis插件Free Mybatis plugin的步骤(推荐)
2022-12-05 02:01:03
Java中MyBatis Plus知识点总结
2023-08-11 14:12:04
Java使用DualPivotQuicksort排序
2022-05-22 20:58:12
5个主流的Java开源IDE工具详解
2021-10-13 06:06:50
Java中反射的学习笔记分享
2021-12-18 14:41:43
SpringCloud可视化链路追踪系统Zipkin部署过程
2023-11-27 04:34:06
Springboot创建子父工程过程图解
2022-09-20 06:06:26
C#中Action和Func的区别
2023-10-20 01:30:08
Android开发flow常见API的使用示例详解
2021-09-25 05:27:49
详谈jvm--Java中init和clinit的区别
2022-01-10 10:35:22
SpringBoot如何通过Feign调用传递Header中参数
2023-11-24 21:39:29
Android中asset文件夹与raw文件夹的区别深入解析
2022-11-22 01:40:34
Java实现配置加载机制
2023-11-26 09:03:38
Kotlin语言编程Regex正则表达式实例详解
2023-06-22 02:06:29
java实现MD5加密的方法小结
2022-02-26 20:01:47