@@ -143,51 +143,41 @@ internal static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
143143 {
144144 ImageHelper . ValidateImage ( nameof ( BitmapToBitmapImage ) , bitmap ) ;
145145
146- // 1. Get the raw data into a WriteableBitmap first.
147- // We use Bgra32 because it matches GDI+ 32bpp format exactly.
148146 var width = bitmap . Width ;
149147 var height = bitmap . Height ;
150- var wbmp = new WriteableBitmap ( width , height , 96 , 96 , PixelFormats . Bgra32 , null ) ;
151148
152- // 2. Lock the Bitmap and the WriteableBitmap to copy bytes directly.
153- // This avoids all the 'for' loops and manual math that causes errors.
149+ // 1. Memory Copy to WriteableBitmap (Your efficient logic)
150+ var wbmp = new WriteableBitmap ( width , height , 96 , 96 , PixelFormats . Bgra32 , null ) ;
154151 var rect = new System . Drawing . Rectangle ( 0 , 0 , width , height ) ;
155- var bmpData = bitmap . LockBits ( rect , ImageLockMode . ReadOnly ,
156- System . Drawing . Imaging . PixelFormat . Format32bppArgb ) ;
152+ var bmpData = bitmap . LockBits ( rect , ImageLockMode . ReadOnly , System . Drawing . Imaging . PixelFormat . Format32bppArgb ) ;
157153
158154 wbmp . Lock ( ) ;
159- // Direct memory copy: No math, no pre-multiplication, no data loss.
160155 unsafe
161156 {
162- Buffer . MemoryCopy (
163- ( void * ) bmpData . Scan0 ,
164- ( void * ) wbmp . BackBuffer ,
165- width * height * 4 ,
166- width * height * 4 ) ;
157+ Buffer . MemoryCopy ( ( void * ) bmpData . Scan0 , ( void * ) wbmp . BackBuffer , width * height * 4 , width * height * 4 ) ;
167158 }
168-
169159 wbmp . AddDirtyRect ( new Int32Rect ( 0 , 0 , width , height ) ) ;
170160 wbmp . Unlock ( ) ;
171161 bitmap . UnlockBits ( bmpData ) ;
172162
173- // 3. Convert to BitmapImage via PNG stream
163+ // 2. The Bridge to BitmapImage
174164 var bitmapImage = new BitmapImage ( ) ;
175165 using ( var stream = new MemoryStream ( ) )
176166 {
177- var encoder = new PngBitmapEncoder ( ) ;
167+ // BMP Encoder is leaner and faster than PNG for internal memory swaps
168+ var encoder = new BmpBitmapEncoder ( ) ;
178169 encoder . Frames . Add ( BitmapFrame . Create ( wbmp ) ) ;
179170 encoder . Save ( stream ) ;
180- stream . Seek ( 0 , SeekOrigin . Begin ) ;
171+ stream . Position = 0 ;
181172
182173 bitmapImage . BeginInit ( ) ;
183- bitmapImage . CacheOption = BitmapCacheOption . OnLoad ;
184- // CRITICAL: This prevents WPF from converting it to Premultiplied Alpha
185174 bitmapImage . CreateOptions = BitmapCreateOptions . PreservePixelFormat ;
175+ bitmapImage . CacheOption = BitmapCacheOption . OnLoad ;
186176 bitmapImage . StreamSource = stream ;
187177 bitmapImage . EndInit ( ) ;
188178 }
189179
190- bitmapImage . Freeze ( ) ; // Make it cross-thread compatible
180+ bitmapImage . Freeze ( ) ;
191181 return bitmapImage ;
192182 }
193183 }
0 commit comments