如何在每像素位图1位上正确地记录Marshal.ReadByte

问题描述 投票:0回答:1

我正在尝试改进我整合在一起的1bpp图像搜索功能。

我引用了鲍勃·鲍威尔的出色网页,以及此处的一些答案,我能够将这个运行良好的例程组合在一起。

void PrintScreen()
{
    keybd_event(VKey.VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0);
    keybd_event(VKey.VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0);
}

Bitmap PrintWindow()
{
    PrintScreen();
    Application.DoEvents();
    if (Clipboard.ContainsImage())
    {
        using (Image img = Clipboard.GetImage())
        {
            if (img != null)
            {
                return new Bitmap(img);
            }
        }
    }
    return PrintWindow();
}

Bitmap GetBlackWhiteAt(Point On, Size PickArea)
{
    // Create a new bitmap.
    using (Bitmap bmp = PrintWindow())
        return bmp.Clone(new Rectangle(On, PickArea), PixelFormat.Format1bppIndexed);
}

/// Credits Bob Powell 1bpp
int GetIndexedPixel(int x, int y, BitmapData data)
{
    var index = (y * data.Stride) + (x >> 3);
    var p = Marshal.ReadByte(data.Scan0, index);
    var mask = (byte)(0x80 >> (x & 0x7));
    return p &= mask;
}

/// Credits digEmAll https://stackoverflow.com/a/3530012/4433847
int SubListIndex(IEnumerable<bool> list, int start, IEnumerable<bool> sublist)
{
    for (int listIndex = start; listIndex < list.Count() - sublist.Count() + 1; listIndex++)
    {
        int count = 0;
        while (count < sublist.Count() && sublist.ElementAt(count).Equals(list.ElementAt(listIndex + count)))
            count++;
        if (count == sublist.Count())
            return listIndex;
    }
    return -1;
}
/// Initialize Search image.
bool[][] ba1;
/// Take picture of visual studio save button on a 1920, x 1080 screen.
using (var bw = GetBlackWhiteAt(new Point(145, 37), new Size(16, 16)))
{
    BitmapData data = bw.LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
    ba1 = new bool[bw.Height][];
    for (int y = 0; y <= bw.Height - 1; y++)
    {
        ba1[y] = new bool[bw.Width];
        for (int x = 0; x <= bw.Width - 1; x++)
        {
            if (GetIndexedPixel(x, y, data) > 0)
            {
                ba1[y][x] = true;
            }
        }
    }
    bw.UnlockBits(data);
}
int SkippedBlackLines = 0;
foreach (bool[] bl1 in ba1)
{
    if (bl1.Any(x => x))
    {
        break;
    }
    else
    {
        SkippedBlackLines++;
    }
}

using (Bitmap SearchWindow = PrintWindow().Clone(new Rectangle(0, 0,Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height), PixelFormat.Format1bppIndexed))
{
    BitmapData data = SearchWindow.LockBits(new Rectangle(0, 0, SearchWindow.Width, SearchWindow.Height), ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);

    bool[][] ba2 = new bool[SearchWindow.Height][];
    for (int y = 0; y <= SearchWindow.Height - 1; y++)
    {
        ba2[y] = new bool[SearchWindow.Width];
        for (int x = 0; x <= SearchWindow.Width - 1; x++)
        {
            if (GetIndexedPixel(x, y, data) > 0)
            {
                ba2[y][x] = true;
            }
        }
    }
    var Base = ba1.Skip(SkippedBlackLines);
    // Skip last
    Base = Base.Take(Base.Count() - 1);
    for (int i = ba2.GetUpperBound(0) - 1; i != 0; i--)
    {
        if (SubListIndex(ba2[i].AsEnumerable(), 0, Base.LastOrDefault()) != -1)
        {
            if (Base.Count() != 1)
            {
                Base = Base.Take(Base.Count() - 1);
            }
            else
            {
                MoveTo(
                    SubListIndex(ba2[i].AsEnumerable(), 0, Base.LastOrDefault()) + (Base.Count() /2),
                    i + (ba1.GetUpperBound(0) / 2));
                ba2 = null;
                ba1 = null;
                break;
            }
        }
    }
    SearchWindow.UnlockBits(data);
}

所以如何减少GetIndexedPixel中对Marshal.ReadByte的调用?任何意见或想法都很好。

c# mouseevent bitmapdata
1个回答
1
投票

如果您使用unsafe关键字,则可以依次使用pointer通过索引提取byte(如果我正确理解了问题)

unsafe关键字表示不安全的上下文,对于任何涉及指针的操作。

byte p = *((byte*)data.Scan0 + index);

为此,必须将您的方法标记为unsafe

unsafe int GetIndexedPixel(int x, int y, BitmapData data)

[[[Note:您将需要设置项目构建选项以允许不安全的代码

© www.soinside.com 2019 - 2024. All rights reserved.