首页 新闻 赞助 找找看

RGB的byte[]怎么转换为bmp文件?

0
悬赏园豆:10 [已解决问题] 解决于 2021-06-10 08:48

RGB的byte[]怎么转换为bmp文件?
要确定可以用的

https://www.cnblogs.com/klkucan/archive/2012/11/19/2777628.html 这个不行,问题不知道在哪里

C#

echo_lovely的主页 echo_lovely | 小虾三级 | 园豆:1406
提问于:2021-05-28 10:03
< >
分享
最佳答案
0
       //最简单的,没有做异常处理,传入rgb的byte数组,然后保存为 filename 文件
       // 按道理是要处理图片的长和宽的,看看是不是4的倍数,不是4的倍数则补成4的倍数
        public static void ConvertRGB2Bmp(byte[] buffer, int width, int height, string filename)
        {
            using (FileStream fs = File.Open(filename, FileMode.Create))
            {
                using (BinaryWriter bw = new BinaryWriter(fs))
                {
                    bw.Write('B');
                    bw.Write('M');//BM  2
                    bw.Write(40 + 14 + buffer.Length);//SIZE  4
                    bw.Write((ushort)0);//bfReserved1       2
                    bw.Write((ushort)0);//bfReserved2       2
                    bw.Write(40 + 14);              //4
                    bw.Write(40);               //4
                    bw.Write(width);
                    bw.Write(height);
                    bw.Write((ushort)1);
                    bw.Write((ushort)24);
                    bw.Write(0);
                    bw.Write(buffer.Length);
                    bw.Write(0);
                    bw.Write(0);
                    bw.Write(0);
                    bw.Write(0);
                    bw.Write(buffer, 0, buffer.Length);

                    bw.Flush();
                }
            }
        }

结果,上黑是因为我的byte[]未全部初始化,默认都是0,然后下半截白是因为我读取的图片转化的rgb数组很奇怪,不仅少,而且还不是3的倍数(24位)

echo_lovely | 小虾三级 |园豆:1406 | 2021-05-28 15:50

周围灰边是win10的图片查看器的灰边

echo_lovely | 园豆:1406 (小虾三级) | 2021-05-28 15:51


随机数填充的效果

echo_lovely | 园豆:1406 (小虾三级) | 2021-05-28 15:58
其他回答(1)
0

https://github.com/tiancai4652/GetPCM/blob/master/Program.cs

前段时间总结的RGB-BMP互转,PCM-WAV互转

看 GetRGBFromBMP, SetRGBToBMP方法,可以自己弄个bmp图片试一下

 /// <summary>
    /// GetRGBFromBMP
    /// </summary>
    /// <param name="bmpFile">bmpFile</param>
    /// <param name="rgbFile">rgbFile</param>
    /// <param name="biWidth">图像宽度(以像素为单位)</param>
    /// <param name="biHeight">图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom</param>
    /// <param name="biBitCount">图像像素位数</param>
    /// <param name="biCompression">压缩方式,0:不压缩,1:RLE8,2:RLE4</param>
    /// <param name="biXPelsPerMeter">用象素/米表示的水平分辨率</param>
    /// <param name="biYPelsPerMeter">用象素/米表示的垂直分辨率</param>
    public static void GetRGBFromBMP(string bmpFile, string rgbFile, out UInt32 biWidth,out UInt32 biHeight, out UInt16 biBitCount,out UInt32 biCompression
         ,out UInt32 biXPelsPerMeter,out UInt32 biYPelsPerMeter)
    {
        using (FileStream stream = new FileStream(bmpFile, FileMode.OpenOrCreate))
        {
            using (BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.ASCII))
            {
                #region  位图文件头(bmp file header):  提供文件的格式、大小等信息
                //2Bytes,必须为"BM",即0x424D 才是Windows位图文件
                string bfType = new string(reader.ReadChars(2));
                //4Bytes,整个BMP文件的大小
                UInt32 bfSize = reader.ReadUInt32();
                //2Bytes,保留,为0
                UInt16 bfReserved1 = reader.ReadUInt16();
                //2Bytes,保留,为0
                UInt16 bfReserved2 = reader.ReadUInt16();
                //4Bytes,文件起始位置到图像像素数据的字节偏移量
                UInt32 bfOffBits = reader.ReadUInt32();
                #endregion

                #region 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
                //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
                UInt32 biSize = reader.ReadUInt32();
                //4Bytes,图像宽度(以像素为单位)
                 biWidth = reader.ReadUInt32();
                //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
                 biHeight= reader.ReadUInt32();
                //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
                UInt16 biPlanes = reader.ReadUInt16();
                //2Bytes,图像像素位数
                 biBitCount = reader.ReadUInt16();
                //4Bytes,0:不压缩,1:RLE8,2:RLE4
                 biCompression = reader.ReadUInt32();
                //4Bytes,4字节对齐的图像数据大小
                UInt32 biSizeImage = reader.ReadUInt32();
                //4 Bytes,用象素/米表示的水平分辨率
                 biXPelsPerMeter = reader.ReadUInt32();
                //4 Bytes,用象素/米表示的垂直分辨率
                 biYPelsPerMeter = reader.ReadUInt32();
                //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
                UInt32 biClrUsed = reader.ReadUInt32();
                //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
                UInt32 biClrImportant = reader.ReadUInt32();
                #endregion

                #region 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
                //1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。
                if (biBitCount == 1 || biBitCount == 4 || biBitCount == 8)
                {
                    //指定蓝色强度
                    byte rgbBlue = reader.ReadByte();
                    //指定绿色强度
                    byte rgbGreen = reader.ReadByte();
                    //指定红色强度
                    byte rgbRed = reader.ReadByte();
                    //保留,设置为0
                    byte rgbReserved = reader.ReadByte();
                }

                #endregion

                #region 位图数据(bitmap data):图像数据区
                //当biBitCount = 1时,8个像素占1个字节;
                //当biBitCount = 4时,2个像素占1个字节;
                //当biBitCount = 8时,1个像素占1个字节;
                //当biBitCount = 24时,1个像素占3个字节;

                //Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,
                //DataSizePerLine = (biWidth * biBitCount + 31) / 8;
                //DataSizePerLine = DataSizePerLine / 4 * 4;
                var dataSizePerLine = (biWidth * biBitCount) / 8;
                if (dataSizePerLine % 4 != 0)
                {
                    dataSizePerLine = (dataSizePerLine / 4 + 1) * 4;
                }
                var dataSize = dataSizePerLine * biHeight;

                #endregion
                var dataBytes = new byte[dataSize];
                for (int i = 0; i < dataSize; i++)
                {
                    dataBytes[i] = reader.ReadByte();
                }
                Stream streamByte = new MemoryStream(dataBytes);
                using (var fileStream = File.Create(rgbFile))
                {
                    streamByte.Seek(0, SeekOrigin.Begin);
                    streamByte.CopyTo(fileStream);
                }
            }

        }
    }
收获园豆:10
猝不及防 | 园豆:2731 (老鸟四级) | 2021-05-28 10:41
    /// <param name="biXPelsPerMeter">用象素/米表示的水平分辨率</param>
    /// <param name="biYPelsPerMeter">用象素/米表示的垂直分辨率</param>

这个是怎么确定的?

支持(0) 反对(0) echo_lovely | 园豆:1406 (小虾三级) | 2021-05-28 11:02

@小草上飞飞:
这个根据你怎么组图片确定的吧,
你可以先用GetRGBFromBMP读取一张图片看看这俩参数输出是啥

支持(0) 反对(0) 猝不及防 | 园豆:2731 (老鸟四级) | 2021-05-28 11:04

@猝不及防:

尽力了

支持(0) 反对(0) echo_lovely | 园豆:1406 (小虾三级) | 2021-05-28 13:49
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册