WPF WriteableBitmap透過GDI+繪製幫助類

HotSky發表於2024-08-05

程式碼:


    public class WriteableBitmapGraphic : IDisposable
    {
        public WriteableBitmap Source { get; private set; }
        public System.Drawing.Bitmap bitmap { get; private set; }
        public int DataLength { get; private set; }
        public Int32Rect SourceRect { get; private set; }
        public System.Drawing.Rectangle BitmapRect { get; private set; }
        public System.Drawing.Graphics Graphics { get; private set; }
        System.Drawing.Imaging.PixelFormat pixelFormat;
        bool flushed = false;
        public WriteableBitmapGraphic(WriteableBitmap writeableBitmap)
        {
            Source = writeableBitmap;
            DataLength = Source.BackBufferStride * Source.PixelHeight;
            SourceRect = new Int32Rect(0, 0, Source.PixelWidth, Source.PixelHeight);
            BitmapRect = ConvertRect(SourceRect);
            pixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
            bitmap = new System.Drawing.Bitmap(writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, pixelFormat);
            Graphics = System.Drawing.Graphics.FromImage(bitmap);
        }
        public void FillSource()
        {
            var block = bitmap.LockBits(BitmapRect, System.Drawing.Imaging.ImageLockMode.WriteOnly, pixelFormat);
            byte[] tempArr = new byte[DataLength];
            Marshal.Copy(Source.BackBuffer, tempArr, 0, DataLength);
            Marshal.Copy(tempArr, 0, block.Scan0, DataLength);
            bitmap.UnlockBits(block);
        }

        public static System.Drawing.SolidBrush CreateBrush(System.Windows.Media.Color color)
        {
            return new System.Drawing.SolidBrush(ConvertColor(color));
        }
        public static System.Drawing.Color ConvertColor(System.Windows.Media.Color color)
        {
            return System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B);
        }
        public static System.Drawing.Rectangle ConvertRect(System.Windows.Int32Rect rect)
        {
            return new System.Drawing.Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
        }

        public void Flush()
        {
            Graphics.Flush();
            var block = bitmap.LockBits(ConvertRect(SourceRect), System.Drawing.Imaging.ImageLockMode.ReadOnly, pixelFormat);
            byte[] tempArr = new byte[DataLength];
            Marshal.Copy(block.Scan0, tempArr, 0, DataLength);
            Source.Lock();
            Source.AddDirtyRect(SourceRect);
            Marshal.Copy(tempArr, 0, Source.BackBuffer, DataLength);
            Source.Unlock();
            bitmap.UnlockBits(block);
            flushed = true;
        }

        public void Dispose()
        {
            if(!flushed)
                Flush();
            Graphics?.Dispose();
            bitmap?.Dispose();
        }
    }

相關文章