软件编程
位置:首页>> 软件编程>> C#编程>> C#合并BitMap图像生成超 * itmap

C#合并BitMap图像生成超 * itmap

作者:记住我Gxy  发布时间:2023-12-08 18:24:11 

标签:C#,合并,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 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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com