views:

1021

answers:

4

Trying to use 300dpi tif images for display on the web. At the moment, when the user uploads an image, I am dynamically creating a thumbnail. If a page is created referencing the high-res image with a width of 500x500px, can I use the same functionality to convert to a gif/jpg on the fly. What is the impending resolution of the jpg that would be created?

EDIT:

To further explain the usage, the user uploads 300dpi images which are approx 3000x3000 pixels. The user is using these images to create a catalog page which will be used for pdf printing. When they are creating the page, we only need 72dpi images to display to the screen, but for print, need the 300dpi images. Obviously they do not want to add a 3000x3000px image to the page, so it needs to be resized to the correct viewing area, e.g. 500x500px etc.

A: 

If I understand what you want - you're trying to make a gif or jpg thumbnail of a very high resolution tif, for web display - if not, I apologize in advance....


If you want the thumbnail to be 500x500px, that is the resolution of the jpg/gif you'll want to create - 500x500, or at least 500x<500 or <500x500 (to fit in the box, unless you want distorted images).

For display on the web, the DPI does not matter. Just use the pixel resolution you wish directly.

Reed Copsey
A: 

Technically the JPG/GIF is created at 72-DPI by the Image classes in .NET. But the DPI really doesn't have any meaning to the browser - it just uses the dimensions 500x500.

Paul Alexander
A: 

When displaying an image on a web, the dpi (or more correctly ppi) setting is irrelevant. It's only the size in pixels that is relevant.

You can convert an image on the fly, but it is very work intensive for the server to do that every time the image is displayed. You should create the sizes that you need when the user uploads the image.

Guffa
+5  A: 

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:

  1. Load the full image. This will be about 27 MB of memory for your 3000x3000 images.
  2. Resize. Lot's of math done lazily (still CPU intensive).
  3. 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"));
Frank Krueger
We are potentially resizing 5-10 images for a page. Considering the tif's can rainge from 17-30mb, how much server load would we be talking?
mickyjtwin
Having worked on the team that developed this library, I can say that our implementation is as fast as anything else out there. But it will be a load on the server: Load the full image, Resize, Compress. Those are all expensive. Spin off a thread to do the work and make sure you have good harddrives
Frank Krueger
The thing is, is that the user could be constantly changing the width and height of the image to fit within their requirements. What if I resaved the image to a 72dpi jpg (approx 100k, down from 17MB). Would this dynamically process faster?
mickyjtwin