Skip to content

Commit bba00ae

Browse files
author
Wayfarer
committed
Fix a leak
1 parent 8e5b441 commit bba00ae

3 files changed

Lines changed: 10 additions & 20 deletions

File tree

-189 Bytes
Loading
-48 Bytes
Loading

Imaging/ImageStreamMedia.cs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)