You'll want to do some filtering and maybe change the average a bit since this is very sensitive to minor color differences on space images but the basic idea here works. It also doesn't deserve a beauty prize but for 10 minutes of work, I wasn't expecting it to. Furthermore this code will fail on any image that's not 24 bits per pixel. class StarGazer { // this function works on pictures of up to 1.3 billion pixels in width public bool[,] toBool(Bitmap bitmap) { Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); bool[,] boolBitmap = new bool[ bitmap.Height,bitmap.Width]; unsafe {//first we calculate the average value of a pixel byte* ptr = (byte*)(bmpData.Scan0); ptr--; ulong overallAvg = 0UL; for(int y = 0;y<bitmap.Height;y++) { ulong lineAvg = 0UL; for (int x = 0; x < bitmap.Width; x++) { lineAvg+= *(++ptr); lineAvg+= *(++ptr); lineAvg+= *(++ptr); } overallAvg += lineAvg /(ulong) bitmap.Width; } overallAvg /= (ulong)bitmap.Height; int average = (int)overallAvg; //we've got the average value a collection of three pixels needs to have to become an object ptr = (byte*)(bmpData.Scan0); ptr--; for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { boolBitmap[y, x] = (*(++ptr) + *(++ptr) + *(++ptr) > average); } } } bitmap.UnlockBits(bmpData); return boolBitmap; } public Bitmap boolBitmap(bool[,] boolBitmap) { Bitmap temp = new Bitmap(boolBitmap.GetLength(1),boolBitmap.GetLength(0)); System.Drawing.Imaging.BitmapData bmpData = temp.LockBits(new Rectangle(0, 0, boolBitmap.GetLength(1), boolBitmap.GetLength(0)), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);