• 8位、24位、32位图像数据转换


    最近调用一个人体检测算法,算法要求输入的是图片的BGR数据,但是拿到的数据是32位Argb数据,算法无法正确进行人体检测,从网上百度文库中搜到一个C#代码,可以进行转换。网上的代码有点乱,整理了一下,记录留存。

    整理后的代码如下:

      1     class BitmapConvertHelp
      2     {
      3          struct BitmapFileHeader 
      4          {
      5              //位图文件头 
      6              public UInt16 bfType; 
      7              public UInt32 bfSize; 
      8              public UInt16 bfReserved1; 
      9              public UInt16 bfReserved2; 
     10              public UInt32 bfOffBits; 
     11          } 
     12         
     13         struct BitmapInfoHeader 
     14         {
     15             //位图信息头 
     16             public UInt32 biSize;
     17             public UInt32 biWidth; 
     18             public UInt32 biHeight; 
     19             public UInt16 biPlanes; 
     20             public UInt16 biBitCount; 
     21             public UInt32 biCompression; 
     22             public UInt32 biSizeImage; 
     23             public UInt32 biXPelsPerMeter;
     24             public UInt32 biYPelsPerMeter; 
     25             public UInt32 biClrUsed; 
     26             public UInt32 biClrImportant; 
     27         } 
     28 
     29         struct RGBQUAD 
     30         {
     31             //位图调色板项
     32             public byte rgbBlue;
     33             public byte rgbGreen;
     34             public byte rgbRed;
     35             public byte rgbReserved; 
     36         } 
     37         
     38         private string filepath = null;//需打开的位图的路径 
     39         private string savepath = null;//转换后位图的保存路径
     40         private BitmapFileHeader bfh; 
     41         private BitmapInfoHeader bih; 
     42        
     43         private void Save8Bits(Bitmap bmp) 
     44         { 
     45             //为位图文件头赋值 
     46             bfh.bfOffBits = 1078;
     47             bfh.bfReserved1 = 0; 
     48             bfh.bfReserved2 = 0; 
     49             bfh.bfSize = 14; 
     50             bfh.bfType = 19778; 
     51             //为位图信息头赋值 
     52             bih.biBitCount = 8; 
     53             bih.biClrImportant = 0; 
     54             bih.biClrUsed = 0; 
     55             bih.biCompression = 0;
     56             bih.biHeight = (uint)bmp.Height; 
     57             bih.biPlanes = 1; 
     58             bih.biSize = 40; 
     59             bih.biSizeImage = (uint)(bmp.Height * ((bmp.Width * 8 + 31) / 32 * 4)); 
     60             bih.biWidth = (uint)bmp.Width; 
     61             bih.biXPelsPerMeter = 0; 
     62             bih.biYPelsPerMeter = 0; 
     63             //构造256色的调色板,非索引图
     64             RGBQUAD[] pal = new RGBQUAD[256]; 
     65             for (int i = 0; i < 256; i++) 
     66             { 
     67                 pal[i].rgbBlue = (byte)i; 
     68                 pal[i].rgbGreen = (byte)i; 
     69                 pal[i].rgbRed = (byte)i; 
     70                 pal[i].rgbReserved = 0; 
     71             } 
     72             FileInfo f = new FileInfo(savepath); 
     73             using (BinaryWriter bw = new BinaryWriter(f.OpenWrite())) 
     74             { 
     75                 //写入文件头 
     76                 bw.Write(bfh.bfType); 
     77                 bw.Write(bfh.bfSize); 
     78                 bw.Write(bfh.bfReserved1);
     79                 bw.Write(bfh.bfReserved2);
     80                 bw.Write(bfh.bfOffBits); 
     81                 //写入信息头 
     82                 bw.Write(bih.biSize); 
     83                 bw.Write(bih.biWidth); 
     84                 bw.Write(bih.biHeight); 
     85                 bw.Write(bih.biPlanes); 
     86                 bw.Write(bih.biBitCount); 
     87                 bw.Write(bih.biCompression);
     88                 bw.Write(bih.biSizeImage); 
     89                 bw.Write(bih.biXPelsPerMeter);
     90                 bw.Write(bih.biYPelsPerMeter); 
     91                 bw.Write(bih.biClrUsed); 
     92                 bw.Write(bih.biClrImportant); 
     93                 //写入调色板 
     94                 for (int i = 0; i < 256; i++) 
     95                 {
     96                     bw.Write(pal[i].rgbBlue); 
     97                     bw.Write(pal[i].rgbGreen); 
     98                     bw.Write(pal[i].rgbRed); 
     99                     bw.Write(pal[i].rgbReserved); 
    100                 } 
    101                 //位图上下翻转 
    102                 bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
    103                 BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); 
    104                 unsafe 
    105                 { 
    106                     byte* ptr = (byte*)data.Scan0.ToPointer();
    107                     //位图的指针 
    108 
    109                     byte[] line = new byte[data.Stride];
    110                     //保存位图的一行 
    111                     for (int i = 0; i < data.Stride; i++) 
    112                         line[i] = 0; 
    113                     for (int i = 0; i < bmp.Height; i++)
    114                     { 
    115                         for (int j = 0; j < bmp.Width; j++) 
    116                         { 
    117                             line[j] = *ptr++; 
    118                         }
    119                         ptr += data.Stride - bmp.Width;//指针跳过对齐的字节
    120                         bw.Write(line, 0, line.Length);//写入位图的一行 
    121                     } 
    122                 } 
    123                 bw.Close();
    124                 bmp.UnlockBits(data);
    125             } 
    126         } 
    127         
    128         public void Bit8To24() 
    129         { 
    130             Bitmap bmp8 = new Bitmap(filepath);
    131             BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
    132             Bitmap bmp24 = new Bitmap(bmp8.Width, bmp8.Height, PixelFormat.Format24bppRgb); 
    133             BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
    134             unsafe 
    135             { 
    136                 byte* ptr8 = (byte*)data8.Scan0.ToPointer(); 
    137                 byte* ptr24 = (byte*)data24.Scan0.ToPointer(); 
    138                 for (int i = 0; i < bmp8.Height; i++) 
    139                 { 
    140                     for (int j = 0; j < bmp8.Width; j++)
    141                     {
    142                         //用8位位图的灰度值填充24位位图的R、G、B值 
    143                         *ptr24++ = *ptr8; 
    144                         *ptr24++ = *ptr8; 
    145                         *ptr24++ = *ptr8++; 
    146                     } 
    147                     ptr8 += data8.Stride - bmp8.Width;                    //跳过对齐字节 
    148                     ptr24 += data24.Stride - bmp8.Width * 3; //跳过对齐字节 
    149                 } 
    150             } 
    151             bmp8.UnlockBits(data8); 
    152             bmp24.UnlockBits(data24); 
    153             bmp24.Save(savepath); 
    154         } 
    155         
    156         public void Bit8To32() 
    157         { 
    158             Bitmap bmp8 = new Bitmap(filepath);
    159             BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
    160             Bitmap bmp32 = new Bitmap(bmp8.Width, bmp8.Height, PixelFormat.Format32bppArgb); 
    161             BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    162            
    163             unsafe 
    164             { 
    165                 byte* ptr8 = (byte*)data8.Scan0.ToPointer(); 
    166                 byte* ptr32 = (byte*)data32.Scan0.ToPointer();
    167                 for (int i = 0; i < bmp8.Height; i++) 
    168                 { 
    169                     for (int j = 0; j < bmp8.Width; j++) 
    170                     {
    171                         //用8位位图的灰度值,填充32位位图的RGB值,透明度为100% 
    172                         *ptr32++ = *ptr8; 
    173                         *ptr32++ = *ptr8; 
    174                         *ptr32++ = *ptr8++; 
    175                         *ptr32++ = 255; 
    176                     } 
    177                     ptr8 += data8.Stride - bmp8.Width; 
    178                     ptr32 += data32.Stride - bmp8.Width * 4;
    179                 }
    180             } 
    181             bmp8.UnlockBits(data8);
    182             bmp32.UnlockBits(data32); 
    183             bmp32.Save(savepath); 
    184         } 
    185         
    186         public void Bit24To8() 
    187         { 
    188             Bitmap bmp24 = new Bitmap(filepath); 
    189             BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    190             Bitmap bmp8 = new Bitmap(bmp24.Width, bmp24.Height, PixelFormat.Format8bppIndexed); 
    191             BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
    192              
    193             unsafe 
    194             { 
    195                 byte* ptr24 = (byte*)data24.Scan0.ToPointer(); 
    196                 byte* ptr8 = (byte*)data8.Scan0.ToPointer(); 
    197                 for (int i = 0; i < bmp8.Height; i++) 
    198                 { 
    199                     for (int j = 0; j < bmp8.Width; j++) 
    200                     {
    201                         //用RGB值的均值作为8位位图的灰度值
    202                         *ptr8++=(byte)(((int)(*ptr24++)+(int)(*ptr24++)+(int)(*ptr24++))/3); 
    203                     } 
    204                     ptr24 += data24.Stride - bmp8.Width * 3; 
    205                     ptr8 += data8.Stride - bmp8.Width; 
    206                 } 
    207             } 
    208             bmp8.UnlockBits(data8);
    209             bmp24.UnlockBits(data24); 
    210             Save8Bits(bmp8); 
    211         } 
    212         
    213         public void Bit32To8() 
    214         {
    215             Bitmap bmp32 = new Bitmap(filepath); 
    216             BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
    217             Bitmap bmp8 = new Bitmap(bmp32.Width, bmp32.Height, PixelFormat.Format8bppIndexed);
    218             BitmapData data8 = bmp8.LockBits(new Rectangle(0, 0, bmp8.Width, bmp8.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
    219             unsafe 
    220             { 
    221                 byte* ptr32 = (byte*)data32.Scan0.ToPointer(); 
    222                 
    223                 byte* ptr8 = (byte*)data8.Scan0.ToPointer(); 
    224                 for (int i = 0; i < bmp8.Height; i++) 
    225                 {
    226                     for (int j = 0; j < bmp8.Width; j++) 
    227                     {
    228                         //用32位位图的RGB值的均值作为8位位图的灰度值 
    229                         *ptr8++ = (byte)(((int)(*ptr32++) + (int)(*ptr32++) + (int)(*ptr32++)) / 3);
    230                         ptr32++;//跳过透明度字节 
    231                     }
    232                     ptr32 += data32.Stride - bmp32.Width * 4; 
    233                     ptr8 += data8.Stride - bmp8.Width; 
    234                 } 
    235             } 
    236             bmp8.UnlockBits(data8); 
    237             bmp32.UnlockBits(data32); 
    238             Save8Bits(bmp8); 
    239         }
    240 
    241         public void Bit32To24() 
    242         { 
    243             Bitmap bmp32 = new Bitmap(filepath); 
    244             BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    245             Bitmap bmp24 = new Bitmap(bmp32.Width, bmp32.Height, PixelFormat.Format24bppRgb); 
    246             BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); 
    247             unsafe 
    248             { 
    249                 byte* ptr32 = (byte*)data32.Scan0.ToPointer(); 
    250                 byte* ptr24 = (byte*)data24.Scan0.ToPointer();
    251                 for (int i = 0; i < bmp24.Height; i++) 
    252                 { 
    253                     for (int j = 0; j < bmp24.Width; j++) 
    254                     {
    255                         //将32位位图的RGB值赋值给24位位图的RGB值 
    256                         *ptr24++ = *ptr32++; 
    257                         *ptr24++ = *ptr32++; 
    258                         *ptr24++ = *ptr32++; 
    259                         ptr32++;//跳过透明度字节 
    260                     } 
    261                     ptr24 += data24.Stride - bmp24.Width * 3;
    262                     ptr32 += data32.Stride - bmp32.Width * 4; 
    263                 } 
    264             }
    265             bmp32.UnlockBits(data32); 
    266             bmp24.UnlockBits(data24);
    267             bmp24.Save(savepath);
    268         }
    269         
    270         public void Bit24To32() 
    271         { 
    272             Bitmap bmp24 = new Bitmap(filepath); 
    273             BitmapData data24 = bmp24.LockBits(new Rectangle(0, 0, bmp24.Width, bmp24.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    274             Bitmap bmp32 = new Bitmap(bmp24.Width, bmp24.Height, PixelFormat.Format32bppArgb); 
    275             BitmapData data32 = bmp32.LockBits(new Rectangle(0, 0, bmp32.Width, bmp32.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 
    276             unsafe
    277             { 
    278                 byte* ptr24 = (byte*)data24.Scan0.ToPointer(); 
    279                 byte* ptr32 = (byte*)data32.Scan0.ToPointer(); 
    280                 for (int i = 0; i < bmp32.Height; i++) 
    281                 {
    282                     for (int j = 0; j < bmp32.Width; j++) 
    283                     {
    284                         //将24位位图的RGB值赋值给32位位图的RGB分量 
    285                         *ptr32++ = *ptr24++; 
    286                         *ptr32++ = *ptr24++; 
    287                         *ptr32++ = *ptr24++; 
    288                         *ptr32++ = 255;//设透明度为100% 
    289                     } 
    290                     ptr24 += data24.Stride - bmp24.Width * 3; 
    291                     ptr32 += data32.Stride - bmp32.Width * 4; 
    292                 } 
    293             } 
    294             bmp32.UnlockBits(data32); 
    295             bmp24.UnlockBits(data24);
    296             bmp32.Save(savepath); 
    297         }
    298     }
  • 相关阅读:
    基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。
    Configuration system failed to initialize
    WebException 请求被中止: 操作超时
    The underlying connection was closed: The connection was closed unexpectedly.
    无法将数据写入传输连接: 在一个非套接字上尝试了一个操作
    C# .NET UDP 形式调用 graylog,gelf
    python3存入redis是bytes
    python commands模块在python3.x被subprocess取代
    subprocess
    nginx重新编译添加ssl模块
  • 原文地址:https://www.cnblogs.com/tlduck/p/9177628.html
Copyright © 2020-2023  润新知