I need to allow my users to upload images for which I need to show a thumbnail. I need to make sure that the thumbnail does not exceed 8000 bytes.
I use nQuant (a color quantizer that creates high-quality 256-color 8-bit PNG images) to quantize the image and reduce it to an 8-bit image rather than 32 bits, which drastically reduces file size.
I want to know what is the maximum image size that will always be under 8000 bytes?
I am currently using 96 x 96 as my maximum sizes and I have not exceeded the 8000 byte limit, but I don’t know if this is due to the original images with which I am testing the converter (194 random images on my HD), or for some other reason.
As I now think about it, I wonder if given that
96 * 96 = 9216 (bytes)
is it correct to assume that my reasoning is mathematically incorrect?
Should I consider reducing the maximum size to
89 * 89 = 7921 (bytes)
For reference, this is a converter:
var fileSystemInfos = new DirectoryInfo(sourcePath).GetFiles();
var i = 0;
var total = fileSystemInfos.Count();
foreach (var file in fileSystemInfos)
{
using (var inputStream = new FileStream(file.FullName, FileMode.Open))
using (var memoryStream = new MemoryStream())
{
using (var sourceBitmap = new Bitmap(inputStream))
{
var img = ResizeImage(sourceBitmap, 96, 96);
QuantizeImage(img, memoryStream);
var outputName = file.Name.Replace("JPG", "png");
using (var outputStream = new FileStream(Path.Combine(outputPath, outputName), FileMode.Create))
{
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(outputStream);
}
}
}
Console.WriteLine(++i + " of " + total);
}
private static void QuantizeImage(Bitmap bmp, MemoryStream outputFile)
{
var quantizer = new WuQuantizer();
using (var quantized = quantizer.QuantizeImage(bmp))
{
try
{
quantized.Save(outputFile, ImageFormat.Png);
}
catch (System.Exception ex)
{
}
}
}
public static Bitmap ResizeImage(Bitmap image, int maxWidth, int maxHeight)
{
int originalWidth = image.Width;
int originalHeight = image.Height;
float ratioX = (float)maxWidth / (float)originalWidth;
float ratioY = (float)maxHeight / (float)originalHeight;
float ratio = Math.Min(ratioX, ratioY);
int newWidth = (int)(originalWidth * ratio);
int newHeight = (int)(originalHeight * ratio);
Bitmap newImage = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(newImage))
{
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawImage(image, 0, 0, newWidth, newHeight);
}
return newImage;
}