44// See LICENSE file in the project root for full license information.
55//
66
7+ using System ;
78using System . Drawing ;
89using System . Drawing . Imaging ;
910
@@ -13,68 +14,99 @@ internal sealed class nanoBitmapProcessor
1314 {
1415 private readonly Bitmap _bitmap ;
1516
16- public nanoBitmapProcessor (
17+ // Bitmap types supported by the native code found in "CLR_GFX_BitmapDescription"
18+ private enum BitmapType
19+ {
20+ // Format of bitmap is 16-bit rgb565 format
21+ nanoCLRBitmap = 0 ,
22+ // Format of bitmap is GIF
23+ Gif = 1 ,
24+ // Format of bitmap JPEG
25+ Jpeg = 2 ,
26+ // Format of bitmap is Windows bitmap
27+ // NOTE: There is support for compressed bitmaps in the native code, but the conversion of resources to Format16bppRgb565
28+ // by the metadata processor eliminates this code being used.
29+ WindowsBmp = 3 ,
30+ // Not supported or unknown bitmap type
31+ UnKnown = 255
32+ }
33+
34+ public nanoBitmapProcessor (
1735 Bitmap bitmap )
1836 {
1937 _bitmap = bitmap ;
2038 }
2139
22- public void Process (
40+ public void Process (
2341 nanoBinaryWriter writer )
2442 {
43+ // CLR_GFX_BitmapDescription header as required by the native side
2544 writer . WriteUInt32 ( ( uint ) _bitmap . Width ) ;
2645 writer . WriteUInt32 ( ( uint ) _bitmap . Height ) ;
2746
2847 writer . WriteUInt16 ( 0x00 ) ; // flags
2948
3049 var nanoImageFormat = GetnanoImageFormat ( _bitmap . RawFormat ) ;
3150
51+ // For GIF and JPEG, we do not convert
3252 if ( nanoImageFormat != 0 )
3353 {
34- writer . WriteByte ( 0x01 ) ; // bpp
35- writer . WriteByte ( nanoImageFormat ) ;
54+ writer . WriteByte ( 0x01 ) ;
55+ writer . WriteByte ( ( byte ) nanoImageFormat ) ;
3656 _bitmap . Save ( writer . BaseStream , _bitmap . RawFormat ) ;
3757 }
3858 else
3959 {
40- writer . WriteByte ( 0x10 ) ; // bpp
41- writer . WriteByte ( nanoImageFormat ) ;
60+ byte bitsPerPixel = 16 ;
61+ writer . WriteByte ( bitsPerPixel ) ;
62+ writer . WriteByte ( ( byte ) nanoImageFormat ) ;
4263
43- var rect = new Rectangle ( Point . Empty , _bitmap . Size ) ;
44- using ( var convertedBitmap =
45- _bitmap . Clone ( new Rectangle ( Point . Empty , _bitmap . Size ) ,
46- PixelFormat . Format16bppRgb565 ) )
64+ try
4765 {
48- var bitmapData = convertedBitmap . LockBits (
49- rect , ImageLockMode . ReadOnly , convertedBitmap . PixelFormat ) ;
50-
51- var buffer = new short [ bitmapData . Stride * convertedBitmap . Height / sizeof ( short ) ] ;
52- System . Runtime . InteropServices . Marshal . Copy (
53- bitmapData . Scan0 , buffer , 0 , buffer . Length ) ;
54-
55- convertedBitmap . UnlockBits ( bitmapData ) ;
56- foreach ( var item in buffer )
66+ Bitmap clone = new Bitmap ( _bitmap . Width , _bitmap . Height , PixelFormat . Format16bppRgb565 ) ;
67+ using ( Graphics gr = Graphics . FromImage ( clone ) )
5768 {
58- writer . WriteInt16 ( item ) ;
69+ gr . DrawImageUnscaled ( _bitmap , 0 , 0 ) ;
5970 }
71+
72+ Rectangle rect = new Rectangle ( 0 , 0 , clone . Width , clone . Height ) ;
73+ BitmapData bitmapData = clone . LockBits ( rect , ImageLockMode . ReadOnly , PixelFormat . Format16bppRgb565 ) ;
74+
75+ // Format16bppRgb565 == 2 bytes per pixel
76+ byte [ ] data = new byte [ clone . Width * clone . Height * 2 ] ;
77+
78+ System . Runtime . InteropServices . Marshal . Copy ( bitmapData . Scan0 , data , 0 , data . Length ) ;
79+ clone . UnlockBits ( bitmapData ) ;
80+ writer . WriteBytes ( data ) ;
81+
82+ }
83+ catch
84+ {
85+ throw new NotSupportedException ( $ "PixelFormat ({ _bitmap . PixelFormat . ToString ( ) } ) could not be converted to Format16bppRgb565.") ;
6086 }
6187 }
6288 }
6389
64- private byte GetnanoImageFormat (
90+ private BitmapType GetnanoImageFormat (
6591 ImageFormat rawFormat )
6692 {
67- if ( rawFormat . Equals ( ImageFormat . Gif ) )
93+ // Any windows bitmap format is marked for conversion to nanoCLRBitmap ( i.e. Format16bppRgb565 )
94+ if ( rawFormat . Equals ( ImageFormat . Bmp ) )
6895 {
69- return 1 ;
96+ return BitmapType . nanoCLRBitmap ;
7097 }
71-
72- if ( rawFormat . Equals ( ImageFormat . Jpeg ) )
98+ else if ( rawFormat . Equals ( ImageFormat . Gif ) )
7399 {
74- return 2 ;
100+ return BitmapType . Gif ;
101+ }
102+ else if ( rawFormat . Equals ( ImageFormat . Jpeg ) )
103+ {
104+ return BitmapType . Jpeg ;
105+ }
106+ else
107+ {
108+ return BitmapType . UnKnown ;
75109 }
76-
77- return 0 ;
78110 }
79111 }
80- }
112+ }
0 commit comments