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 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;
        }

到此这篇关于C#合并BitMap图像生成超大bitmap的文章就介绍到这了,更多相关C#合并BitMap内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C# Bitmap图像处理加速的实现

    目录 BitmapData类 传统代码 使用BitmapData的代码 效率对比 代码 GPU加速 生成Dll 调用Dll 耗时 BitmapData类 BitmapData类专门用于位图处理,与Bitmap的不同点在于,它使用指针直接修改内存,而Bitmap是使用SetPixel()方法间接修改颜色,因此其效率远远超过SetPixel() 传统代码 以灰度处理为例,为了便于演示,此处的灰度算法采用 Gray=(R+G+B) / 3 private void Gray_Tradition() {

  • c# 实现位图算法(BitMap)

    算法原理 BitMap的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素.由于采用了Bit为单位来存储数据,因此可以大大节省存储空间. BitMap可以看成一种数据结构. 假设有这样一个需求:在20亿个随机整数中找出某个数m是否存在其中,并假设32位操作系统,4G内存. 在Java中,int占4字节,1字节=8位(1 byte = 8 bit). 如果每个数字用int存储,那就是20亿个int,因而占用的空间约为 (2000000000*4/1024/1024/102

  • c# Bitmap转bitmapImage高效方法

    网上有很多人都记录以下方法进行转换,这个方法存在一个问题,就是低效,我在进行图片拼接时,图片大了之后就会很慢.所以我有找了一个高效的替代方法. public BitmapImage BitmapToBitmapImage(System.Drawing.Bitmap bitmap) { System.Drawing.Bitmap bitmapSource = new System.Drawing.Bitmap(bitmap.Width, bitmap.Height); int i, j; for

  • C# Bitmap 复制的小例子

    复制代码 代码如下: public Bitmap CopyBitmap(Bitmap source){    int depth = Bitmap.GetPixelFormatSize(source.PixelFormat); if (depth != 8 && depth != 24 && depth != 32)    {        return null;    } Bitmap destination = new Bitmap(source.Width, sou

  • C#合并BitMap图像生成超大bitmap

    当只需要两个图像合并的时候,可以简单的使用gdi+,把两个图像画到一个画布上面实现合并bitmap. 当需要将许多bitmap合并时,由于bitmap类限制,长度或宽度太大时会报异常,前面这种方法就行不通了. 由于bitmapp属于位图格式,了解图像格式后,发现,bitmap文件的第3-8位存储了文件大小信息,第19-22位存储了高度信息,第23-26位存储了宽度信息.文件头后面都是像素的argb,并无其它信息.于是,试想一下,如果把第二张图像的像素argb放到第一张后面,并修改第一张的文件头信

  • Android Bitmap详解及Bitmap的内存优化

    Android Bitmap详解及Bitmap的内存优化 一.Bitmap: Bitmap是Android系统中的图像处理的最重要类之一.用它可以获取图像文件信息,进行图像剪切.旋转.缩放等操作,并可以指定格式保存图像文件. 常用方法: public void recycle() // 回收位图占用的内存空间,把位图标记为Dead public final boolean isRecycled() //判断位图内存是否已释放 public final int getWidth() //获取位图的

  • android中圆角图像生成方法

    本文实例讲述了android中圆角图像生成方法.分享给大家供大家参考.具体分析如下: 在android开发中为了美观,常常要求ImageView中显示出圆角图像的效果,这个如何实现? 这里总结了网上的最优方法:将图像处理成圆角,然后在加载给ImageView显示,代码如下: public Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.get

  • PHP GD库相关图像生成和处理函数小结

    本文总结了PHP GD库相关图像生成和处理函数.分享给大家供大家参考,具体如下: 这几天在学习图像验证码部分,参考了许多例子,都是用GD库来生成和绘制图像的,所以打算把GD库封装成类来使用,顺便也学习和练习一下PHP面向对象部分. 首先分析一下GD库所提供的函数,依据功能作了划分:(这只是常用的基础级函数,更高级的函数稍后再作研究) 1. create // 图像生成 A.绘制图像 imageCreate // 基于调色板(256色)的图像(gif/*) imageCreateTrueColor

  • Android Canvas和Bitmap结合绘图详解流程

    目录 Rect/RectF Matrix Canvas Bitmap Rect/RectF 存储四个值的矩形类:左侧.顶部.右侧和底部.可用于直接在画布上绘制或仅用于存储要绘制的对象的大小.Rect和RectF类之间的区别在于 RectF 存储浮点值,而Rect类存储整数. private static Bitmap createDrawableBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth(); int he

  • ASP.NET生成图形验证码的方法详解

    本文实例讲述了ASP.NET生成图形验证码的方法.分享给大家供大家参考,具体如下: 通常生成一个图形验证码主要 有3个步骤: (1)随机产生一个长度为N的随机字符串,N的值可由开发可由开发人员自行设置.该字符串可以包含数字.字母等. (2)将随机生成的字符串创建成图片,并显示. (3)保存验证码. 新建一个页面为default.aspx,  放置一个TextBox控件和一个Image控件,TextBox控件用于输入生成的字符串,Image控件用于显示字符串,它的图片就为生成的图形验证码image

  • asp.net生成字母和数字混合图形验证码

    验证码技术是网站开发过程中比较重要的技术,可以防止非法人员利用注册机或者登陆工具来攻击我们的网站.下面是效果图: 具体实现方法如下: 1.主要思路是:引用Using System.Drawing命名空间,利用Graphics的FromImage方法创建一个画布,同时设置画布的宽和高,然后通过Graphics类 的DrawString方法随机生成的字符串绘制到画布中,绘制验证码的同时,在画布中利用SetPixel方法绘制一些色点,从而防止非法人员利用机器 人来进行登陆.当我们绘制验证码完毕后,在需

  • asp.net中3种验证码示例(实现代码)(数字,数字字母混和,汉字)

    效果如图所示: Default.aspx 复制代码 代码如下: <table> <tr> <td class="style1">  (验证码测试)</td> <td>   <asp:Label ID="Label1" runat="server"></asp:Label>   <asp:Image ID="Image1" runat=&q

  • asp.net 简单验证码验证实现代码

    首先是新建一个验证码页面 ValidateCode.aspx 定义变量 这样有利于后期的修改了 复制代码 代码如下: private int codeLen = 4;//验证码长度 private int fineness = 85;//图片清晰度 private int imgWidth = 48;//图片宽度 private int imgHeight = 24;//图片高度 private string fontFamily = "Times New Roman";//字体名称

  • asp.net验证码的简单制作

    实际上关于asp.net验证码制作的文章已经很多很多了,但是今天还是要和大家继续分享,亲,可以综合几篇实例,编写出适用于自己网站的ASP.NET验证码,大概也就两大部分: 先建立一个asp.net窗体ValidateCode.aspx:不写任何东西.直接在后台ValidateCode.aspx.cs中写如下代码: protected void Page_Load(object sender, EventArgs e) { string validateCode = CreateValidateC

随机推荐