这篇文章主要介绍C#合并BitMap图像如何生成超大bitmap,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
当只需要两个图像合并的时候,可以简单的使用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 h2 = Convert.ToInt32(hexHeight.Substring(0, 2), 16); int h3 = Convert.ToInt32(hexHeight.Substring(2, 2), 16); int h4 = Convert.ToInt32(hexHeight.Substring(4, 2), 16); int h5 = Convert.ToInt32(hexHeight.Substring(6, 2), 16); byte[] sizeHeight = new byte[] { (byte)h5, (byte)h4, (byte)h3, (byte)h2 }; 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; }
以上是“C#合并BitMap图像如何生成超大bitmap”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。