@@ -30,68 +30,91 @@ public static (string, ImageFormat) GetMimeType(string path)
3030 }
3131
3232 public static byte [ ] BlendImageWithColor (
33- byte [ ] imageBytes ,
34- double fade ,
35- Autodesk . Revit . DB . Color flatColor ,
36- ImageFormat mimeType )
33+ byte [ ] imageBytes ,
34+ double fade ,
35+ Autodesk . Revit . DB . Color flatColor ,
36+ ImageFormat mimeType ,
37+ Autodesk . Revit . DB . Color tintColor )
3738 {
38- if ( fade >= 1.0 )
39- return imageBytes ;
39+ bool noFlatBlend = fade >= 1.0 || flatColor == null ;
40+ if ( noFlatBlend && tintColor == null )
41+ return imageBytes ;
4042
41- float fFade = Clamp ( ( float ) fade , 0f , 1f ) ;
42- float fInv = 1f - fFade ;
4343
44- float lr = SrgbToLinear ( flatColor . Red / 255f ) ;
45- float lg = SrgbToLinear ( flatColor . Green / 255f ) ;
46- float lb = SrgbToLinear ( flatColor . Blue / 255f ) ;
44+ float fFade = noFlatBlend ? 1f
45+ : Clamp ( ( float ) fade , 0f , 1f ) ;
46+ float fInv = 1f - fFade ; // 0 if no blend
4747
48- byte [ ] resultBytes ;
48+ // face colour in linear space (0 if unused)
49+ float lrFlat = 0f , lgFlat = 0f , lbFlat = 0f ;
50+ if ( ! noFlatBlend )
51+ {
52+ lrFlat = SrgbToLinear ( flatColor . Red / 255f ) ;
53+ lgFlat = SrgbToLinear ( flatColor . Green / 255f ) ;
54+ lbFlat = SrgbToLinear ( flatColor . Blue / 255f ) ;
55+ }
56+
57+ // tint factors (1,1,1 ⇒ no change)
58+ float lrTint = 1f , lgTint = 1f , lbTint = 1f ;
59+ if ( tintColor != null )
60+ {
61+ lrTint = SrgbToLinear ( tintColor . Red / 255f ) ;
62+ lgTint = SrgbToLinear ( tintColor . Green / 255f ) ;
63+ lbTint = SrgbToLinear ( tintColor . Blue / 255f ) ;
64+
65+ lrTint = Math . Min ( lrTint + 0.10f , 1.0f ) ;
66+ lgTint = Math . Min ( lgTint + 0.10f , 1.0f ) ;
67+ lbTint = Math . Min ( lbTint + 0.10f , 1.0f ) ;
68+ }
4969
50- using ( MemoryStream inputMs = new MemoryStream ( imageBytes ) )
51- using ( Bitmap bitmap = new Bitmap ( inputMs ) )
70+ byte [ ] resultBytes ;
71+ using ( var inputMs = new MemoryStream ( imageBytes ) )
72+ using ( var bitmap = new Bitmap ( inputMs ) )
5273 {
5374 Rectangle rect = new Rectangle ( 0 , 0 , bitmap . Width , bitmap . Height ) ;
54- BitmapData data = bitmap . LockBits (
55- rect ,
56- ImageLockMode . ReadWrite ,
57- PixelFormat . Format32bppArgb ) ;
75+ BitmapData data = bitmap . LockBits ( rect , ImageLockMode . ReadWrite ,
76+ PixelFormat . Format32bppArgb ) ;
5877
5978 int byteCount = Math . Abs ( data . Stride ) * bitmap . Height ;
6079 byte [ ] pixels = new byte [ byteCount ] ;
6180 Marshal . Copy ( data . Scan0 , pixels , 0 , byteCount ) ;
6281
6382 for ( int i = 0 ; i < byteCount ; i += 4 )
6483 {
65- // bytes BGRA → float 0-1
84+ //BGRA → linear
6685 float sb = pixels [ i + 0 ] / 255f ;
6786 float sg = pixels [ i + 1 ] / 255f ;
6887 float sr = pixels [ i + 2 ] / 255f ;
69-
70- // sRGB → lineal
71- float lbSrc = SrgbToLinear ( sb ) ;
72- float lgSrc = SrgbToLinear ( sg ) ;
73- float lrSrc = SrgbToLinear ( sr ) ;
74-
75- // lineal interpolation
76- float lbMix = lbSrc * fFade + lb * fInv ;
77- float lgMix = lgSrc * fFade + lg * fInv ;
78- float lrMix = lrSrc * fFade + lr * fInv ;
79-
80- pixels [ i + 0 ] = ( byte ) ( Clamp ( LinearToSrgb ( lbMix ) , 0f , 1f ) * 255f + 0.5f ) ;
81- pixels [ i + 1 ] = ( byte ) ( Clamp ( LinearToSrgb ( lgMix ) , 0f , 1f ) * 255f + 0.5f ) ;
82- pixels [ i + 2 ] = ( byte ) ( Clamp ( LinearToSrgb ( lrMix ) , 0f , 1f ) * 255f + 0.5f ) ;
88+ float lb = SrgbToLinear ( sb ) ;
89+ float lg = SrgbToLinear ( sg ) ;
90+ float lr = SrgbToLinear ( sr ) ;
91+
92+ // BLEND WITH FLAT COLOUR
93+ lb = lb * fFade + lbFlat * fInv ;
94+ lg = lg * fFade + lgFlat * fInv ;
95+ lr = lr * fFade + lrFlat * fInv ;
96+
97+ //APPLY TINT
98+ lb *= lbTint ;
99+ lg *= lgTint ;
100+ lr *= lrTint ;
101+
102+ //* linear → sRGB, write back
103+ pixels [ i + 0 ] = ( byte ) ( Clamp ( LinearToSrgb ( lb ) , 0f , 1f ) * 255f + 0.5f ) ;
104+ pixels [ i + 1 ] = ( byte ) ( Clamp ( LinearToSrgb ( lg ) , 0f , 1f ) * 255f + 0.5f ) ;
105+ pixels [ i + 2 ] = ( byte ) ( Clamp ( LinearToSrgb ( lr ) , 0f , 1f ) * 255f + 0.5f ) ;
106+ // alpha (pixels[i+3]) untouched
83107 }
84108
85109 Marshal . Copy ( pixels , 0 , data . Scan0 , byteCount ) ;
86110 bitmap . UnlockBits ( data ) ;
87111
88- using ( MemoryStream outputMs = new MemoryStream ( ) )
112+ using ( var outputMs = new MemoryStream ( ) )
89113 {
90114 bitmap . Save ( outputMs , mimeType ) ;
91115 resultBytes = outputMs . ToArray ( ) ;
92116 }
93117 }
94-
95118 return resultBytes ;
96119 }
97120
0 commit comments