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     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM