Hi,
I have a load of images stored in zip files. I am trying to return the image from my Web Api 2 application. Can anyone suggest a clever way to return the stream directly from the zip and then dispose of it (code below)?
I'm considering scrapping the 'zip' plan and storing the images as flat files, but there are literally millions of them. I worry about how much space they will take on disk.
I am looking for the fastest possible way to deliver the image from the time of request. That is my main concern for this PoC.
Thanks ^_^
Andy
What I have tried:
Currently I am copying the stream to a memory stream:
I store the path as "C:\ImageLib\1045.zip\GS67801_POS_Image.jpg"
private Stream GetImageByItemCode(string itemCode)
{
var item = ItemType.SelectByItemCode(itemCode).FirstOrDefault();
if (item == null)
return null;
if (item.PosImagePath == null)
return null;
MemoryStream ms = new MemoryStream();
if (item.PosImagePath.IndexOf(".zip") > 0)
{
var zipPath = item.PosImagePath.Substring(0, item.PosImagePath.IndexOf(".zip") + 4);
var filename = item.PosImagePath.Substring(item.PosImagePath.IndexOf(".zip") + 5);
var zipFile = ZipFile.Open(zipPath, ZipArchiveMode.Read);
var entry = zipFile.Entries.Where(e => e.FullName == filename).FirstOrDefault();
if (entry == null)
return null;
entry.Open().CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
}
return ms;
}
This is a PoC so I haven't optimized how I store the filename atm. That's just detail I can deal with later.
This method is used to create an HttpResponse:
public HttpResponseMessage GetImageImg(string itemCode, int size)
{
Stream imageStream = GetImageByItemCode(itemCode);
var response = Request.CreateResponse();
if (imageStream == null)
{
return response;
}
response.Content = new StreamContent(imageStream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
return response;
}
which is returned by my controller here:
[Route("{itemCode}/{size:int?}")]
public object GetImage(string itemCode, int size = 1)
{
var query = Request.GetQueryNameValuePairs().ToDictionary(p => p.Key.ToLower(), p => p.Value.ToLower());
var format = "img";
if (query.ContainsKey("format"))
{
format = query["format"];
}
switch (format)
{
default:
return GetImageImg(itemCode, size);
}
}
Don't worry about all that formatting crap. Eventually the size / format will be stored in my lib as separate files.