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
}
}
}
}
}