X3

RedSky

导航

WPF WriteableBitmap通过GDI+绘制帮助类

代码:


    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 = DrawingUtil.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 void DrawImage(byte[] pixelArray, int width, int height, int x, int y)
        {
            using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, pixelFormat))
            {
                var block = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat);
                Marshal.Copy(pixelArray, 0, block.Scan0, pixelArray.Length);
                bitmap.UnlockBits(block);
                DrawImage(bitmap, x, y);
            }
        }
        public void DrawImage(string imagePath, Point point)
        {
            using (var image = System.Drawing.Image.FromFile(imagePath))
                DrawImage(image, point);
        }
        public void DrawImage(System.Drawing.Image image, Point point)
        {
            DrawImage(image, (int)point.X, (int)point.Y);
        }
        public void DrawImage(System.Drawing.Image image, int x, int y)
        {
            Graphics.DrawImage(image, x, y);
        }


        public void ClearRandom()
        {
            Random random = new Random();
            var block = bitmap.LockBits(BitmapRect, System.Drawing.Imaging.ImageLockMode.ReadOnly, pixelFormat);
            int offset = 0;
            int n256 = 256;
            unsafe
            {
                byte* ptr = (byte*)block.Scan0;
                do
                {
                    ptr[offset++] = (byte)random.Next(n256);
                } while (offset < DataLength);
            }
            bitmap.UnlockBits(block);
        }

        public void Flush()
        {
            Graphics.Flush();
            var block = bitmap.LockBits(BitmapRect, 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();
        }

        public void Clear(Color color)
        {
            Graphics.Clear(DrawingUtil.ConvertColor(color));
        }
    }
    public static class DrawingUtil
    {
        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 class CvGraphic : IDisposable
    {
        public WriteableBitmap Source { get; private set; }
        public OpenCvSharp.Mat SourceMat { get; private set; }
        public int Length { get; private set; }
        bool flushed = false;
        public CvGraphic(WriteableBitmap source)
        {
            Source = source;
            Length = source.PixelHeight * source.BackBufferStride;
            SourceMat = OpenCvSharp.Mat.FromPixelData(source.PixelHeight, source.PixelWidth, OpenCvSharp.MatType.CV_8UC4, source.BackBuffer);
        }
        public void Clear()
        {
            OpenCvSharp.Cv2.Randn(SourceMat, new OpenCvSharp.Vec4b(0, 0, 0, 0), new OpenCvSharp.Vec4b(0, 0, 0, 0));
        }

        public void Random()
        {
            OpenCvSharp.Cv2.Randn(SourceMat, new OpenCvSharp.Vec4b(0, 0, 0, 0), new OpenCvSharp.Vec4b(255, 255, 255, 255));
        }

        public void DrawImage(string filename, int x, int y)
        {
            if (x >= Source.PixelWidth || y >= Source.PixelHeight) return;
            using(OpenCvSharp.Mat mat = new OpenCvSharp.Mat(filename, OpenCvSharp.ImreadModes.Unchanged))
            {
                int width = Math.Min(SourceMat.Width - x, mat.Width);
                int height = Math.Min(SourceMat.Height - y, mat.Height);
                mat.CopyTo(SourceMat.SubMat(new OpenCvSharp.Range(x, x + width), new OpenCvSharp.Range(y, y + height)));
            }
        }

        public void Flush()
        {
            Source.WritePixels(new Int32Rect(0, 0, Source.PixelWidth, Source.PixelHeight), SourceMat.Data, Length, Source.BackBufferStride);
            flushed = true;
        }
        public void Dispose()
        {
            if(flushed)
                Flush();
            SourceMat?.Dispose();
        }
    }

 

posted on 2024-08-05 18:14  HotSky  阅读(8)  评论(0编辑  收藏  举报