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     }

 

posted on 2018-06-13 14:27  淹死的鸭子  阅读(5518)  评论(0编辑  收藏  举报

导航