4
4
// See LICENSE file in the project root for full license information.
5
5
//
6
6
7
+ using System ;
7
8
using System . Drawing ;
8
9
using System . Drawing . Imaging ;
9
10
@@ -13,68 +14,99 @@ internal sealed class nanoBitmapProcessor
13
14
{
14
15
private readonly Bitmap _bitmap ;
15
16
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 (
17
35
Bitmap bitmap )
18
36
{
19
37
_bitmap = bitmap ;
20
38
}
21
39
22
- public void Process (
40
+ public void Process (
23
41
nanoBinaryWriter writer )
24
42
{
43
+ // CLR_GFX_BitmapDescription header as required by the native side
25
44
writer . WriteUInt32 ( ( uint ) _bitmap . Width ) ;
26
45
writer . WriteUInt32 ( ( uint ) _bitmap . Height ) ;
27
46
28
47
writer . WriteUInt16 ( 0x00 ) ; // flags
29
48
30
49
var nanoImageFormat = GetnanoImageFormat ( _bitmap . RawFormat ) ;
31
50
51
+ // For GIF and JPEG, we do not convert
32
52
if ( nanoImageFormat != 0 )
33
53
{
34
- writer . WriteByte ( 0x01 ) ; // bpp
35
- writer . WriteByte ( nanoImageFormat ) ;
54
+ writer . WriteByte ( 0x01 ) ;
55
+ writer . WriteByte ( ( byte ) nanoImageFormat ) ;
36
56
_bitmap . Save ( writer . BaseStream , _bitmap . RawFormat ) ;
37
57
}
38
58
else
39
59
{
40
- writer . WriteByte ( 0x10 ) ; // bpp
41
- writer . WriteByte ( nanoImageFormat ) ;
60
+ byte bitsPerPixel = 16 ;
61
+ writer . WriteByte ( bitsPerPixel ) ;
62
+ writer . WriteByte ( ( byte ) nanoImageFormat ) ;
42
63
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
47
65
{
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 ) )
57
68
{
58
- writer . WriteInt16 ( item ) ;
69
+ gr . DrawImageUnscaled ( _bitmap , 0 , 0 ) ;
59
70
}
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.") ;
60
86
}
61
87
}
62
88
}
63
89
64
- private byte GetnanoImageFormat (
90
+ private BitmapType GetnanoImageFormat (
65
91
ImageFormat rawFormat )
66
92
{
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 ) )
68
95
{
69
- return 1 ;
96
+ return BitmapType . nanoCLRBitmap ;
70
97
}
71
-
72
- if ( rawFormat . Equals ( ImageFormat . Jpeg ) )
98
+ else if ( rawFormat . Equals ( ImageFormat . Gif ) )
73
99
{
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 ;
75
109
}
76
-
77
- return 0 ;
78
110
}
79
111
}
80
- }
112
+ }
0 commit comments