0

I'd like to change the following code into an efficient Web API controller method that can return 30 to 50 JPEGs (for <20 simultaneous users) of average 3MB size.

    public async Task<HttpResponseMessage> Get(int imageid) {
        return await Task.Run(() => {
            var dzImage = _dataContext.DeepZoomImages.SingleOrDefault(_ => _.ImageID == imageid);
            if (dzImage == default(DeepZoomImage)) {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
            }
            var response = new HttpResponseMessage(HttpStatusCode.OK);
            var bitmap = GetFullSizeBitmap(dzImage);
            var memoryStream = new MemoryStream();
            bitmap.Save(memoryStream, ImageFormat.Jpeg);
            response.Content = new ByteArrayContent(memoryStream.ToArray());
            var fileName = string.Format("{0}.jpg", dzImage.ImageName);
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName };
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
            memoryStream.Flush();
            return response;
        });
    }

The foregoing method handles one image. How can I best pluralize it to handle multiple images efficiently for this usage/load scenario? Is it possible to return Task<HttpResponseMessage>[] or Task<HttpResponseMessage[]>?

Or would it be better generate all images and return them in one go?

Thanks for your help...

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
CalvinDale
  • 9,005
  • 5
  • 29
  • 38
  • Define 'efficient'. Are you trying to improve server load or HTTP traffic? Are these images cacheable? Could you cache the generated image on the server? Could you allow the client to cache image tiles locally? At 3MB per image, the per-request overhead of HTTP doesn't seem terrible. If you do wrap them up in a single payload how will you consume them from Javascript? – Ian Mercer Jan 28 '13 at 17:37
  • These tend to be one-off requests to download ad-hoc collections of images. So server-side caching wouldn't be particularly beneficial. the images are stored in a database. I simply want to make it easy for a user in China on a slow connection to download 40 or 50 images at a time. I suspect a user would prefer to have images trickle in sequentially. And I don't want an individual mega-request to bog down the server for other users. – CalvinDale Jan 28 '13 at 18:56
  • The deep zoom scenario typically works best with individually fetched tiles that are cached by the browser. This allows the user to zoom in and back out and get an instant refresh or to pan in one direction and to fetch just one strip of new tiles. Client-side caching is likely the best option here, not bundling images to reduce HTTP overhead - their browser should already be requesting multiple images in parallel for well written client code and the size of these images is such that the HTTP overhead is small. What does the calling code look like? – Ian Mercer Jan 28 '13 at 20:59
  • The client scenario is as follows. The user displays a web page which contains a collection of Seadragon Ajax Viewers. Each viewer shows an individual Deep Zoom image pyramid. The user then requests local copies of the full-size source images (from which the DZ pyramids are generated). In this application our users have occasion to browse 30 to 50 images and may subsequently decide to download them all. So I would like to know how to facilitate this scenario efficiently using the ASP.NET Web API on the server and Javascript/JQuery on the client and by using a single button click. – CalvinDale Jan 28 '13 at 21:22
  • In that case your best bet may be to create a ZIP file containing them all and download that one file to them. ZIP won't decrease the size by much at all for images but it will give you the single-file download that you seek and the users will still be able to get to all the individual images. See also http://stackoverflow.com/questions/9612416/html5-multiple-file-downloader-looking-for-better-option-than-single-zip-via-z – Ian Mercer Jan 28 '13 at 23:16

1 Answers1

0

Based on our discussion the best approach here would be to create a ZIP file on the server and then download that one file to the user. As an alternative you could try this multi-file download approach.

Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
  • Thanks for your help Ian. I basically arrived at the same conclusion that dynamically generating a ZIP file and returning it would serve my purpose. But so far I'm having some difficulty getting it implemented using DotNetZip library. But it probably warrants a separate question. – CalvinDale Jan 29 '13 at 00:24