This boils down to a simple image resize. The discussion of DPIs is just ancillary data to calculate the scale factor.
As @Guffa said, you should do this at the time of the upload so that you can just serve static images in your viewer.
This will be a load on the server:
- Load the full image. This will be about 27 MB of memory for your 3000x3000 images.
- Resize. Lot's of math done lazily (still CPU intensive).
- Compress. More CPU + Cost of writing to your drive.
Since you are already taking the time to generate a thumbnail, you can amortize that cost and this cost by not having to repeat Step 1 above (see the code).
After an image is uplaoded, I would recommend spinning off a thread to do this work. It's a load on the web server for sure, but you're only other option is to devote a second machine to performing the work. It will have to be done eventually.
Here is some code to do the job. The important lines are these:
OutputAsJpeg(Resize(big, 300.0, 72.0), new FileStream("ScreenView.jpg"));
OutputAsJpeg(Resize(big, bigSize, 64.0), new FileStream("Thumbnail.jpg"));
We can resize the big
image however we need. In the first line we just scale it down by a fixed scale (72.0 / 300.0). On the second line, we force the image to have a final max dimension of 64 (scale factor = 64.0 / 3000.0).
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
BitmapSource Resize(BitmapSource original,
double originalScale,
double newScale) {
double s = newScale / originalScale;
return new TransformedBitmap(original, new ScaleTransform(s, s));
}
void OutputAsJpeg(BitmapSource src, Stream out) {
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(src));
encoder.Save(out);
}
// Load up your bitmap from the file system or whatever,
// then dump it out to a smaller version and a thumbnail.
// Assumes thumbnails have a max dimension of 64
BitmapSource big = new BitmapImage(new Uri("BigPage0.png",
UriKind. RelativeOrAbsolute));
double bigSize = Math.Max(big.PixelWidth, big.PixelHeight);
OutputAsJpeg(Resize(big, 300.0, 72.0), new FileStream("ScreenView.jpg"));
OutputAsJpeg(Resize(big, bigSize, 64.0), new FileStream("Thumbnail.jpg"));