C#应用 - 05.怎么分割bmp图像和raw图像_c# 图像分割_阿财继续努力的博客-程序员秘密

技术标签: C#  c#  # C#应用  

  1. bmp图像含有头数据,一般长度为54个字节,像素按照从左到右,从下到上的顺序排列;raw图像不含头数据,且像素为1个字节,因此直接分割即可,像素按照从左到右,从上到下的顺序排列。
  2. bmp图像按照从左到右,从下到上的顺序依次输出编号为[1,rowCount*colCount]的bmp图像;raw图像按照从左到右,从上到下的顺序依次输出编号为[1,rowCount*colCount]的raw图像。
  3. 注意,rowCount和colCount必须为原图高度和宽度的整数因子。
using System;
using System.IO;

namespace _05
{
    
    class Program
    {
    
        static void Main(string[] args)
        {
    
            Test.DivideBmpImage("D:\\Desktop\\Files\\Directory\\BmpImage.bmp", 2, 4, "D:\\Desktop\\Files\\Directory");
            Test.DivideRawImage("D:\\Desktop\\Files\\Directory\\RawImage.raw", 10800, 21600, 2, 4, "D:\\Desktop\\Files\\Directory");
        }
    }

    class Test
    {
    
        /// <summary>
        /// 根据给定的行数和列数,分割bmp图像
        /// bmp图像含有头数据,一般长度为54个字节,像素按照从左到右,从下到上的顺序排列
        /// 注意,头数据以2个或4个字节为单位,按照十六进制倒序排列,因此,只能调用BitConverter类的方法进行修改
        /// 按照从左到右,从下到上的顺序依次输出编号为[1,rowCount*colCount]的bmp图像
        /// 注意,rowCount和colCount必须为原图高度和宽度的整数因子
        /// </summary>
        /// <param name="sourceImagePath">原图路径</param>
        /// <param name="rowCount">行数</param>
        /// <param name="colCount">列数</param>
        /// <param name="outputDirectory">输出目录</param>
        public static void DivideBmpImage(string sourceImagePath, int rowCount, int colCount, string outputDirectory)
        {
    
            //获取原数据
            byte[] sourceData = File.ReadAllBytes(sourceImagePath);

            //提取头数据
            int headSize = BitConverter.ToInt32(sourceData, 10);//头数据大小,单位为字节
            byte[] headData = new byte[headSize];
            for (int i = 0; i < headSize; i++)
            {
    
                headData[i] = sourceData[i];
            }

            //提取像素数据
            int width = BitConverter.ToInt32(headData, 18);//图像宽度,单位为像素
            int height = BitConverter.ToInt32(headData, 22);//图像高度,单位为像素
            int pixelSize = BitConverter.ToInt32(headData, 28) / 8;//单个像素大小,单位为字节
            int widthSize = width * pixelSize;//图像宽度,单位为字节
            int heightSize = height;//图像高度,单位为字节
            byte[][] pixelData = new byte[heightSize][];
            for (int i = 0; i < heightSize; i++)
            {
    
                pixelData[i] = new byte[widthSize];
                for (int j = 0; j < widthSize; j++)
                {
    
                    pixelData[i][j] = sourceData[headSize + i * widthSize + j];
                }
            }

            //重建头数据
            byte[] newHeadData = new byte[headSize];
            for (int i = 0; i < headSize; i++)
            {
    
                newHeadData[i] = headData[i];
            }
            int newFileSize = headSize + (widthSize / colCount) * (heightSize / rowCount);
            byte[] newFileSize_ = BitConverter.GetBytes(newFileSize);
            for (int i = 0; i < newFileSize_.Length; i++)
            {
    
                newHeadData[2 + i] = newFileSize_[i];
            }
            int newWidth = width / colCount;
            byte[] newWidth_ = BitConverter.GetBytes(newWidth);
            for (int i = 0; i < newWidth_.Length; i++)
            {
    
                newHeadData[18 + i] = newWidth_[i];
            }
            int newHeight = height / rowCount;
            byte[] newHeight_ = BitConverter.GetBytes(newHeight);
            for (int i = 0; i < newHeight_.Length; i++)
            {
    
                newHeadData[22 + i] = newHeight_[i];
            }
            int newPixelSize = BitConverter.ToInt32(headData, 34) / (rowCount * colCount);
            byte[] newPixelSize_ = BitConverter.GetBytes(newPixelSize);
            for (int i = 0; i < newPixelSize_.Length; i++)
            {
    
                newHeadData[34 + i] = newPixelSize_[i];
            }

            //重建像素数据
            int newWidthSize = newWidth * pixelSize;
            int newHeightSize = newHeight;
            //原图按行分割
            byte[][][][] newPixelData = new byte[rowCount][][][];
            for (int i = 0; i < rowCount; i++)
            {
    
                //原图按列分割
                newPixelData[i] = new byte[colCount][][];
                for (int j = 0; j < colCount; j++)
                {
    
                    //新图按行分割
                    newPixelData[i][j] = new byte[newHeightSize][];
                    for (int m = 0; m < newHeightSize; m++)
                    {
    
                        //新图按列分割
                        newPixelData[i][j][m] = new byte[newWidthSize];
                        for (int n = 0; n < newWidthSize; n++)
                        {
    
                            newPixelData[i][j][m][n] = pixelData[i * newHeightSize + m][j * newWidthSize + n];
                        }
                    }
                }
            }

            //重建图片并输出
            byte[] newData;
            for (int i = 0; i < rowCount; i++)
            {
    
                for (int j = 0; j < colCount; j++)
                {
    
                    newData = new byte[newFileSize];
                    //加入头数据
                    for (int k = 0; k < headSize; k++)
                    {
    
                        newData[k] = newHeadData[k];
                    }
                    //加入像素数据
                    for (int m = 0; m < newHeightSize; m++)
                    {
    
                        for (int n = 0; n < newWidthSize; n++)
                        {
    
                            newData[headSize + m * newWidthSize + n] = newPixelData[i][j][m][n];
                        }
                    }
                    //输出
                    File.WriteAllBytes($"{
      outputDirectory}\\{
      i * colCount + j + 1}.bmp", newData);
                }
            }
        }

        /// <summary>
        /// 根据给定的行数和列数,分割raw图像
        /// raw图像不含头数据,且像素为1个字节,因此直接分割即可,像素按照从左到右,从上到下的顺序排列
        /// 按照从左到右,从上到下的顺序依次输出编号为[1,rowCount*colCount]的raw图像
        /// 注意,rowCount和colCount必须为原图高度和宽度的整数因子
        /// </summary>
        /// <param name="sourceImagePath">原图路径</param>
        /// <param name="rowCount">行数</param>
        /// <param name="colCount">列数</param>
        /// <param name="outputDirectory">输出目录</param>
        public static void DivideRawImage(string sourceImagePath, int heightSize, int widthSize, int rowCount, int colCount, string outputDirectory)
        {
    
            //获取原数据
            byte[] sourceData = File.ReadAllBytes(sourceImagePath);

            //提取像素数据
            byte[][] pixelData = new byte[heightSize][];
            for (int i = 0; i < heightSize; i++)
            {
    
                pixelData[i] = new byte[widthSize];
                for (int j = 0; j < widthSize; j++)
                {
    
                    pixelData[i][j] = sourceData[i * widthSize + j];
                }
            }

            //重建像素数据
            int newWidthSize = widthSize / colCount;
            int newHeightSize = heightSize / rowCount;
            //原图按行分割
            byte[][][][] newPixelData = new byte[rowCount][][][];
            for (int i = 0; i < rowCount; i++)
            {
    
                //原图按列分割
                newPixelData[i] = new byte[colCount][][];
                for (int j = 0; j < colCount; j++)
                {
    
                    //新图按行分割
                    newPixelData[i][j] = new byte[newHeightSize][];
                    for (int m = 0; m < newHeightSize; m++)
                    {
    
                        //新图按列分割
                        newPixelData[i][j][m] = new byte[newWidthSize];
                        for (int n = 0; n < newWidthSize; n++)
                        {
    
                            newPixelData[i][j][m][n] = pixelData[i * newHeightSize + m][j * newWidthSize + n];
                        }
                    }
                }
            }

            //重建图片并输出
            byte[] newData;
            for (int i = 0; i < rowCount; i++)
            {
    
                for (int j = 0; j < colCount; j++)
                {
    
                    newData = new byte[newHeightSize * newWidthSize];
                    //加入像素数据
                    for (int m = 0; m < newHeightSize; m++)
                    {
    
                        for (int n = 0; n < newWidthSize; n++)
                        {
    
                            newData[m * newWidthSize + n] = newPixelData[i][j][m][n];
                        }
                    }
                    //输出
                    File.WriteAllBytes($"{
      outputDirectory}\\{
      i * colCount + j + 1}.raw", newData);
                }
            }
        }
    }
}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44021223/article/details/121452562

智能推荐

JVM学习笔记(七)类加载机制-类加载的时机、过程_淡淡的倔强的博客-程序员秘密

前言   Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程。  与那些在编译时需要进行连接工作的语言不同,在java语言里,类型的加载,连接和初始化过程都是在程序运行期间完成的,这种策略虽然会令类加载时稍微增加一些性能开销,但是会为java应用程序提供高度的灵活性,在java里天生可以

Linux bond 网卡绑定配置教程_weixin_34050427的博客-程序员秘密

1.创建bond网卡文件在/etc/sysconfig/network-scripts/ 目录下创建ifcfg-bond0命令:vi /etc/sysconfig/network-scripts/ifcfg-bond0或者复制物理网卡也行: cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/netwo...

关于org.hibernate.ObjectNotFoundException: No row with the given identifier exist_phantomes的博客-程序员秘密

       最近由于项目升级,外部接口变动,于是对数据库表的数据进行了一定的更新操作,当然,没有改变表的结构,后来部署时,即报错如下: 严重: Servlet.service() for servlet default threw exceptionorg.hibernate.ObjectNotFoundException: No row with the given identi...

桥接路由器总是掉线_无线路由器桥接完整教程(不会断网)【图文详解】_weixin_39859055的博客-程序员秘密

无线路由器桥接完整教程(不会断网)【图文详解】路由器桥接是很实用的功能,但网上很多方法不完整,导致路由器桥接是成功了,但副路由经常断网。原因呢?网上很多教程都有这一步:在设置副路由(B路由,从路由)的时候都关闭了DHCP服务器-----动态主机设置协议,导致所有连接到副路由的设备都无法得到IP地址(有些人开启了,但没有进行正确设置,所以也不能正常上网)(正确的设置是不能关闭DHCP的,但要设置对。...

Android 观察者与被观察者_jimtrency的博客-程序员秘密

最近正好闲来无事,正好做完项目,由于里面用到了RxJava,有些许体会,但今天我在这儿,并不会讲RXjava,任何事情都有个循序渐进的过程,后续我会陆续讲RXJAVA并用很通俗的语言,毕竟我每次看到一些博客都有太多专业术语,导致理解起来困难.若你给出了专业术语,你也该解释下啥.废话不说了,下面我们就来讲解观察者与被观察者.Observer 观察者,说白了就是观察别人.(你这不是,废话吗!)Obs

Linux文件服务器之Samba共享目录_牧野香香的博客-程序员秘密

tipssamba新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入samba/etc/samba/smb.conf[data] comment = data path = /data #secu

随便推点

WebSocket handshake Unexpected response code 403_兴国First的博客-程序员秘密

有时客户端发出websocket请求时,前端会显示如下报错:index.js:9 WebSocket connection to 'ws://127.0.0.1:8080/shop/ws?uid=3224458&amp;sid=826' failed: Error during WebSocket handshake: Unexpected response code: 403原因:从S...

前端调用第三方接口跨域问题(淘宝)_我最洋气的博客-程序员秘密

前端调用第三方接口跨域问题&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;百度了好久,大部分的文章都前篇一律的说jsonp跨域,要不就是说配置CROS。看到那种文章出处应该都是一家,心好累。首先来说淘宝目前的接口是不支持jsonp请求的,配置CROS更是无稽之谈。&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先想...

tensorflow tf.is_gpu_available() (判断GPU是否可用)_tf-gpu的 is_vailable_Dontla的博客-程序员秘密

@tf_export("test.is_gpu_available")def is_gpu_available(cuda_only=False, min_cuda_compute_capability=None): """Returns whether TensorFlow can access a GPU. 返回TensorFlow是否可以访问GPU。 Args: cud...

wp8开发基础(2)-webbrowser之js通讯交互(ObjectForScripting,ScriptNotify)_skyhh的博客-程序员秘密

使用wp8的webbrowser想实现如下功能1:能用c#调用包含html中的js2:能用html中的js调用c#中方法注意:一开始找WebBrowser的js通讯交互,看到blog地址:http://blog.csdn.net/zzzzzzzert/article/details/7787481但在wp8中始终不好使原来:普通C#的WebBrows

嵌入式实时操作系统μc/os-Ⅱ学习心得_weixin_38850456的博客-程序员秘密

学习μc/os-Ⅱ操作系统一周时间,本来信心满满的打算一周搞定μc/os-Ⅱ嵌入式实时操作系统,可能是我太年轻想的太简单了,等我接触了才知道,原来其实如此的复杂,涉及的知识面也挺广。我学习μc/os-Ⅱ操作系统的初衷是把它移植到DSP中的,我的研究课题是单相PWM整流,MCU选的是TI的C28系列TMS320F28335,至于为什么要上操作系统呢,说实话,主要是显着圆满一些。查了下资料,我这款芯片...

org.springframework.beans.factory.BeanCreationExce_iamnk2008的博客-程序员秘密

[size=medium]org.springframework.beans.factory.BeanCreationException问题解决org.apache.catalina.core.ApplicationContext log严重: action: nullorg.springframework.beans.factory.BeanCreationException: Erro...

推荐文章

热门文章

相关标签