RightpointLabs.Pourcast.Infrastructure.Services.FaceRecognitionService.ResizePictureForDetection C# (CSharp) Method

ResizePictureForDetection() private method

Scales down the byte size of the image by reducing dimensions and/or introducing compression. It aims to get it under 2MB so the web service won't reject it.
private ResizePictureForDetection ( byte data ) : byte[]
data byte
return byte[]
        private byte[] ResizePictureForDetection(byte[] data)
        {
            const int maxLength = 2*1000*1000; // be conservative
            if (data == null || data.Length < maxLength)
                return data;

            using (var ms = new MemoryStream(data))
            {
                using (var rawImage = (Bitmap) Image.FromStream(ms))
                {
                    log.DebugFormat("Image is too big @ {0} bytes, {1}x{2}, shrinking", data.Length, rawImage.Width, rawImage.Height);

                    // too big - try some measures to downsize things
                    for (var cutSize = 1;; cutSize++)
                    {
                        // first, let's cut the image down
                        using (var smallerImage = new ResizeBilinear(rawImage.Width/cutSize, rawImage.Height/cutSize).Apply(rawImage))
                        {
                            log.DebugFormat("Sized down to {0}x{1}", smallerImage.Width, smallerImage.Height);

                            // now, see what a PNG would be...
                            var png = ImageHelper.GetBytes(s => smallerImage.Save(s, ImageFormat.Png));
                            log.DebugFormat("PNG is {0} bytes", png.Length);
                            if (png.Length < maxLength)
                                return png;

                            // too big, try JPEG @ Q100
                            var jpgQ100 = ImageHelper.GetBytes(s => smallerImage.Save(s, ImageHelper.JPEGEncoder(), ImageHelper.Quality(100)));
                            log.DebugFormat("JPG@Q100 is {0} bytes", jpgQ100.Length);
                            if (jpgQ100.Length < maxLength)
                                return jpgQ100;

                            // too big, try JPEG @ Q99
                            var jpgQ99 = ImageHelper.GetBytes(s => smallerImage.Save(s, ImageHelper.JPEGEncoder(), ImageHelper.Quality(99)));
                            log.DebugFormat("JPG@Q99 is {0} bytes", jpgQ99.Length);
                            if (jpgQ99.Length < maxLength)
                                return jpgQ99;

                            // too big, try JPEG @ Q95
                            var jpgQ95 = ImageHelper.GetBytes(s => smallerImage.Save(s, ImageHelper.JPEGEncoder(), ImageHelper.Quality(95)));
                            log.DebugFormat("JPG@Q95 is {0} bytes", jpgQ95.Length);
                            if (jpgQ95.Length < maxLength)
                                return jpgQ95;

                            // still too big, guess we'll have to use a smaller image
                        }
                    }
                }
            }
        }