I hope this is an interesting question for some people.
I want to create some pixels on randomized positions on an image, but the randomizing should be depended on the brightness, so the possibility to create a pixel should be high on a bright part of the image and low on a dark part (but still possible).
Lets take this image for example:
I want to create a function SetRandomizedPixel which will get the bitmap and sets a pixel on a randomized position. The possibility that the pixel will be created on position 1 should be high, on position 2 medium and on position 3 low.
I'm working with C# and Bitmap/Graphic, but that should not matter.
The only thing I need is a suggestion how to start because I can't figure out a good way to archive this.
Maybe read the brightness and positions of all image pixels and sort the list by brightness - but how can I do a randomize which prefer the brighter areas then?
UPDATE: Working on the answer
The following code results in images like this:
But if we look closer there are a lot of pixels on the left side:
That's the code (C#/MVC3):
public ActionResult RandomTest()
{
const int points = 500;
Bitmap bitmap = new Bitmap(Server.MapPath("~/Files/random-test.jpg"));
Random random = new Random();
int imageWidth = bitmap.Width;
int imageHeight = bitmap.Height;
float[][] weightedPixels = ConvertImageToGrayScale(bitmap);
float totalValue = weightedPixels.Sum(i => i.Sum());
for (var y = 0; y < imageHeight - 1; y++)
{
for (var x = 0; x < imageWidth - 1; x++)
{
weightedPixels[y][x] /= totalValue;
}
}
for (var i = 0; i < points; i++)
{
double randomNumber = random.NextDouble();
double currentSum = 0;
for (var y = 0; y < imageHeight - 1; y++)
{
for (var x = 0; x < imageWidth - 1; x++)
{
currentSum += weightedPixels[y][x];
if (currentSum >= randomNumber)
{
bitmap.SetPixel(x, y, Color.Red);
break;
}
}
}
}
// output
var stream = new MemoryStream();
bitmap.Save(stream, ImageFormat.Png);
return File(stream.ToArray(), "image/png");
}
public float[][] ConvertImageToGrayScale(Bitmap bm)
{
var b = new Bitmap(bm);
var data = new List<float[]>();
for (var i = 0; i < b.Width; i++)
{
var row = new List<float>();
for (int x = 0; x < b.Height; x++)
{
var oc = b.GetPixel(i, x);
var grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
row.Add(grayScale);
}
data.Add(row.ToArray());
}
return data.ToArray();
}