gpt4 book ai didi

c# - 从 PictureBox 中获取指定颜色的所有像素点

转载 作者:行者123 更新时间:2023-11-30 18:27:55 27 4
gpt4 key购买 nike

我想在 C# 中获取指定颜色的所有像素(来自 ARGB 或来自 Color 类的任何像素)。我的第一个想法是将图片框内容绘制到 Bitmap 中,然后使用 for 循环,使用 b.GetPixel(x, y);< 遍历像素。但是,我使用的 PictureBox 很大,因此需要几百万/几千万次迭代来检查它,这对性能来说太不友好了。有没有人有比这更好的解决方案?谢谢

最佳答案

我为 System.Drawing.Image 编写了扩展方法,它遍历图像中的每个像素并返回一个包含每个 x/y 坐标的列表作为 System.Drawing.Point。
您可以搜索 rgb 值或 rgba 值。
我的方法是使用指针,所以你需要为你的项目启用不安全代码。
与 GetPixel(...) 相比,使用指针迭代位图要快很多倍。
在此博客条目中,声称 GetPixel(...) 与基于指针的解决方案相比要慢 1000 多倍。
http://davidthomasbernal.com/blog/2008/03/14/c-image-processing-performance-unsafe-vs-safe-code-part-ii/
您应该在使用此代码之前对其进行适当的测试,但即使某些地方不正确,所显示的技术也应该可以帮助您入门!

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

public static class Pixelcounter
{
private struct PixeldataARGB
{
public byte b;
public byte g;
public byte r;
public byte a;
}

private struct PixeldataRGB
{
public byte b;
public byte g;
public byte r;
}

public static IEnumerable<Point> CountOccurences(this Image @this, int r, int g, int b)
{
if (r < 0 || g < 0 || b < 0)
throw new ArgumentException("color values must not be negative");
if (r > 255 || g > 255 || b > 255)
throw new ArgumentException("color values must be below 256");

return CountOccurences(@this, (byte)r, (byte)g, (byte)b);
}

public static unsafe IEnumerable<Point> CountOccurences(this Image @this, byte r, byte g, byte b)
{
Bitmap bitmap = new Bitmap(@this);
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
PixeldataRGB* pointer = (PixeldataRGB*)bitmapData.Scan0;

List<Point> pointList = new List<Point>();

for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Width; x++)
{
PixeldataRGB current = *pointer;
if (current.r == r && current.g == g && current.b == b)
pointList.Add(new Point(x, y));
pointer++;
}
}

bitmap.Dispose();

return pointList;
}

public static IEnumerable<Point> CountOccurences(this Image @this, int r, int g, int b, int a)
{
if (r < 0 || g < 0 || b < 0 || a < 0)
throw new ArgumentException("color and alpha values must not be negative");
if (r > 255 || g > 255 || b > 255 || a > 255)
throw new ArgumentException("color and alpha values must be below 256");

return CountOccurences(@this, (byte)r, (byte)g, (byte)b, (byte)a);
}

public static unsafe IEnumerable<Point> CountOccurences(this Image @this, byte r, byte g, byte b, byte a)
{
Bitmap bitmap = new Bitmap(@this);
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
PixeldataARGB* pointer = (PixeldataARGB*)bitmapData.Scan0;

List<Point> pointList = new List<Point>();

for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Width; x++)
{
PixeldataARGB current = *pointer;
if (current.r == r && current.g == g && current.b == b && current.a == a)
pointList.Add(new Point(x, y));
pointer++;
}
}

bitmap.Dispose();

return pointList;
}
}

关于c# - 从 PictureBox 中获取指定颜色的所有像素点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25941166/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com