Created
December 14, 2017 11:46
-
-
Save VisualMelon/f6a8679e633e347ec32006fbc128dd24 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static Rectangle GetBrightestRectangle(this Bitmap bitmap, int width, int height) | |
{ | |
// Each rectangle's value is its average pixel color. | |
var rectangles = new Dictionary<Rectangle, float>(); | |
// Iterate through all possible rectangle points. | |
for (var x = 0; x < bitmap.Width - width; x++) | |
for (var y = 0; y < bitmap.Height - height; y++) | |
{ | |
var brightnesses = new List<float>(); | |
// Iterate through all rectangle pixels. | |
for (var w = x; w < x + width; w++) | |
for (var h = y; h < y + height; h++) | |
{ | |
brightnesses.Add(bitmap.GetPixel(w, h).GetBrightness()); | |
} | |
rectangles.Add(new Rectangle(x, y, width, height), brightnesses.Average()); | |
} | |
// The brightness ranges from 0.0 through 1.0, where 0.0 represents black and 1.0 represents white. | |
return rectangles.OrderByDescending(pair => pair.Value).First().Key; | |
} | |
public static Rectangle GetBrightestRectangle2(this Bitmap bitmap, int rectWidth, int rectHeight) | |
{ | |
int hSumWidth = bitmap.Width - rectWidth + 1; | |
int hSumHeight = bitmap.Height; | |
float[,] hSums = new float[hSumWidth, hSumHeight]; | |
Queue<float> queue = new Queue<float>(rectWidth); | |
// I would never use `var` in a for-loop; makes it immediately obvious we are using ints and not floats | |
for (int y = 0; y < bitmap.Height; y++) | |
{ | |
for (int x = 0; x < bitmap.Width; x++) | |
{ | |
// this is the only time we call bitmap.GetPixel(,) | |
queue.Enqueue(bitmap.GetPixel(x, y).GetBrightness()); | |
if (x >= rectWidth) | |
{ | |
hSums[x - rectWidth, y] = queue.Sum(); | |
// if the ring-buffer isn't fixed size, we may have to manually evict the old value at this point | |
queue.Dequeue(); | |
} | |
} | |
queue.Clear(); // we don't need to do this, but it is much clearer if we do | |
} | |
queue = new Queue<float>(rectHeight); | |
float bestAverage = float.NegativeInfinity; | |
Rectangle bestRectangle = default(Rectangle); | |
for (int x = 0; x < hSumWidth; x++) | |
{ | |
for (int y = 0; y < bitmap.Height; y++) | |
{ | |
queue.Enqueue(hSums[x, y]); | |
if (y >= rectHeight) | |
{ | |
float rectangleAverage = queue.Average(); | |
if (rectangleAverage > bestAverage) | |
{ | |
bestRectangle = new Rectangle(x, y - rectHeight, rectWidth, rectHeight); | |
bestAverage = rectangleAverage; | |
} | |
// if the ring-buffer isn't fixed size, we may have to manually evict the old value at this point | |
queue.Dequeue(); | |
} | |
} | |
queue.Clear(); | |
} | |
return bestRectangle; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment