c#清除内存中的位图

时间:2018-03-28 16:45:50

标签: c#

我使用此代码:捕获屏幕,迭代其像素并显示一个消息框,如果检测到包含指定颜色的像素。

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace App
{
    public class API
    {
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("gdi32.dll", ExactSpelling = true)]
        public static extern IntPtr BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);

        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();
    }

    internal class ScreenShot
    {
        public static Bitmap Take()
        {
            int screenWidth = Screen.PrimaryScreen.Bounds.Width;
            int screenHeight = Screen.PrimaryScreen.Bounds.Height;

            Bitmap screenBmp = new Bitmap(screenWidth, screenHeight);
            Graphics g = Graphics.FromImage(screenBmp);

            IntPtr dc1 = API.GetDC(API.GetDesktopWindow());
            IntPtr dc2 = g.GetHdc();

            API.BitBlt(dc2, 0, 0, screenWidth, screenHeight, dc1, 0, 0, 13369376);

            // Clean up
            API.ReleaseDC(API.GetDesktopWindow(), dc1);
            g.ReleaseHdc(dc2);
            g.Dispose();

            return screenBmp;
        }
    }

    public class MyClass
    {
        public static void DoIt()
        {
            Bitmap bmp = ScreenShot.Take();

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int bytes = bmpData.Stride * bmp.Height;
            byte[] rgbValues = new byte[bytes];
            byte[] r = new byte[bytes / 3];
            byte[] g = new byte[bytes / 3];
            byte[] b = new byte[bytes / 3];

            // Copy the RGB values into the array.
            Marshal.Copy(ptr, rgbValues, 0, bytes);

            int count = 0;
            int stride = bmpData.Stride;

            for (int column = 0; column < bmpData.Height; column++)
            {
                for (int row = 0; row < bmpData.Width; row++)
                {
                    int B = (rgbValues[(column * stride) + (row * 3)]);
                    int G = (rgbValues[(column * stride) + (row * 3) + 1]);
                    int R = (rgbValues[(column * stride) + (row * 3) + 2]);

                    if (R == 216 && G == 42 && B == 34)
                    {
                        count++;
                    }

                    // MessageBox.Show(R.ToString() + "," + G.ToString() + "," + B.ToString());

                    /* b[count] = (byte)(rgbValues[(column * stride) + (row * 3)]);
                    g[count] = (byte)(rgbValues[(column * stride) + (row * 3) + 1]);
                    r[count++] = (byte)(rgbValues[(column * stride) + (row * 3) + 2]); */
                }
            }

            bmp.Dispose();

            if(count >= 1) MessageBox.Show("Found it " + count.ToString() + " times");
        }
    }
}

我这样调用MyClass():

Task.Run(() =>
            {
                while (true)
                {
                    MyClass.DoIt();
                }
            });

然而,该应用程序很快就会达到约。 2 GB的内存和更多。这基本上是一个内存泄漏,因为每次使用的位图都没有被释放&#34;。我该如何解决这个问题?

0 个答案:

没有答案