/// <summary> /// Generates a set of swatches based on an image passed in; default number of swatches is 7 /// </summary> /// <param name="image">Bitmap of image that we want to generate swatches </param> /// <returns>Array of swatchDTOs (essentially int arrays of RGB values) representing 7 colors picked based on whatever algorithm we use</returns> private SwatchDTO[] GenerateColorSwatches(Bitmap image) { // set up our variables: the pixel count and the area of the bitmap for easy reference const int PIXEL_COUNT = 3; BitmapData bmpData = null; var bmpArea = image.Width * image.Height; // create the array that will hold the rgb values as well as the one that will hold the hsv values var pixelBois = new byte[bmpArea * PIXEL_COUNT]; var hsvValues = new Hsv[bmpArea]; try { bmpData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat); // or PixelFormat.Format24bppRgb // copy the bytes into a byte array the length of the image's dimensions * 3 (for each R G B value) Marshal.Copy(bmpData.Scan0, pixelBois, 0, pixelBois.Length); } finally { image.UnlockBits(bmpData); } for (int i = 0; i < pixelBois.Length; i += PIXEL_COUNT) { // create a color object with the RGB values reversed as the storage from the int* pointer goes BGR // Shout out to github.com/programmingthomas for helping resolve this problem var c = Color.FromArgb(pixelBois[i + 2], pixelBois[i + 1], pixelBois[i]); // convert it to HSV and store it in the corresponding HSV array (divided by 3 since each represents a whole pixel value) hsvValues[i / PIXEL_COUNT] = new Hsv(c); } var hsvSwatches = SortByHueAndFormatHsvValues(hsvValues.ToList()); var rgbSwatches = hsvSwatches.Select(hsv => new SwatchDTO(hsv.ToRGB())).ToArray(); return(rgbSwatches); }