我想在C#中獲取指定顏色的所有像素(來自ARGB或來自Color
類的任何類型)。我的第一個想法是將picturebox內容繪製成Bitmap
,然後使用for
循環,使用b.GetPixel(x, y);
遍歷像素。但是,我使用的PictureBox非常龐大,因此需要花費數百萬/數千萬次的迭代來檢查這個問題,這在性能上不友好。有沒有人有比這更好的解決方案?謝謝從PictureBox獲取指定顏色的所有像素
3
A
回答
0
我寫了System.Drawing.Image的擴展方法,它遍歷圖像中的每個像素,並返回一個包含每個x/y座標的List作爲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;
}
}
相關問題
- 1. 從圖像中獲取像素顏色
- 2. 從CCRenderTexture獲取像素的顏色
- 3. 獲取圖像中的所有顏色
- 4. FreeImage:獲取像素顏色
- 5. GDAL獲取像素顏色
- 6. Java - 獲取像素顏色
- 7. 從Kinect Depth Stream獲取像素顏色
- 8. 如何從像素獲取顏色? OpenGL
- 9. 從NSImage獲取像素和顏色
- 10. 從圖片中獲取像素顏色?
- 11. 如何獲取網頁上任何指定像素的顏色?
- 12. 獲取窗口中指定像素的顏色
- 13. 用C獲取所有屏幕像素顏色#
- 14. 如何從圖片框中獲取特定像素的顏色?
- 15. 獲取像素的顏色在Android的
- 16. 顏色有色UIImages獲得像素化
- 17. WriteableImage - 如何獲取像素的顏色?
- 18. 獲取UIImage的像素顏色
- 19. Java獲取像素的顏色LIVE
- 20. 獲取AVCaptureSession或AVCaptureVideoPreviewLayer的像素顏色
- 21. 獲取rMagick中像素的顏色
- 22. Dart - 獲取ImageElement的像素顏色
- 23. 從picturebox中獲取圖像
- 24. 用另一種顏色更改所有像素的顏色
- 25. 如何從圖像中獲取像素的顏色?
- 26. iOS:從圖像的每個像素獲取頂部顏色
- 27. 從Vaadin的圖像獲取像素顏色
- 28. 通過畫布獲取現有base64圖像的像素顏色
- 29. 嘗試獲取像素顏色
- 30. 使用Magick獲取像素顏色++
您正在尋找[Bitmap.Lockbits](http://msdn.microsoft.com/en-us/library/5ey6h79d(v = vs.110).aspx)。 – 2014-09-19 19:46:00
我幾乎沒有看到你如何驗證每個像素,並選擇你想要的,而不檢查每個像素。看起來你被困在O(n)中,除非你使用了一種會降低準確性的啓發式方法(如預測周圍像素)。這就像試圖在不經過每個元素的情況下對一個數組進行計數一樣,你被限制爲O(n),這是不可能的。你可能會發現的選擇可能都是在內部逐個查看每個像素。 – 2014-09-19 19:50:31
您想要處理的圖像有多大?也許使用早先評論中提到的'Lockbits()',並將它與不安全的圖像處理代碼結合起來,可以讓你獲得可以接受的性能,儘管檢查每個像素。 – 2014-09-19 20:45:23