views:

2322

answers:

3

I am currently writing a system that stores meta data for around 140,000 ish images stored within a legacy image library that are being moved to cloud storage. I am using the following to get the jpg data...

System.Drawing.Image image = System.Drawing.Image.FromFile("filePath");

Im quite new to image manipulation but this is fine for getting simple values like width, height, aspect ratio etc but what I cannot work out is how to retrieve the physical file size of the jpg expressed in bytes. Any help would be much appreciated.

Thanks

Final solution including an MD5 hash of the image for later comparison

System.Drawing.Image image = System.Drawing.Image.FromFile(filePath);

if (image != null)
{
  int width = image.Width;
  int height = image.Height;
  decimal aspectRatio = width > height ? decimal.divide(width, height) : decimal.divide(height, width);  
  int fileSize = (int)new System.IO.FileInfo(filePath).Length;

  using (System.IO.MemoryStream stream = new System.IO.MemoryStream(fileSize))
  {
    image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
    Byte[] imageBytes = stream.GetBuffer();
    System.Security.Cryptography.MD5CryptoServiceProvider provider = new System.Security.Cryptography.MD5CryptoServiceProvider();
    Byte[] hash = provider.ComputeHash(imageBytes);

    System.Text.StringBuilder hashBuilder = new System.Text.StringBuilder();

    for (int i = 0; i < hash.Length; i++)
    {
      hashBuilder.Append(hash[i].ToString("X2"));
    }

    string md5 = hashBuilder.ToString();
  }

  image.Dispose();

}
+2  A: 

If you get your image directly from file, you can use the following code to get size of original file in bytes.

 var fileLength = new FileInfo(filePath).Length;

If you get your image from other source, like getting one bitmap and composing it with other image, like adding watermark you will have to calculate size in run-time. You can't just use original file size, because compressing may lead to different size of output data after modification. In this case, you can use MemoryStream to save image to:

long jpegByteSize;
using (var ms = new MemoryStream(estimatedLength)) // estimatedLength can be original fileLength
{
    image.Save(ms, ImageFormat.Jpeg); // save image to stream in Jpeg format
    jpegByteSize = ms.Length;
 }
Ilya Ryzhenkov
Yes that works perfectly. Bit of a noob question I know but I havn't done much file based work. THanks
Nick Allen - Tungle139
Thanks again llya! I'm directly accessing the image from the file system with no additional manipulation, so the first solution works for that, I'm also thinking of storing an MD5 hash of the image to check for updated images and I believe the MemoryStream class will allow me to get at the bytes
Nick Allen - Tungle139
I do not think it is a noob question. I like these kind of questions. Not working with a certain aspect of the .NET framework on a daily basis, makes you forget stuff. This serves as a quick reference to anyone.
Marthinus
A: 

System.Drawing.Image won't give you the file length of size. You have to use another library for that.

int lengthoffile = (new System.IO.FileInfo(sFullPath)).Length;

MysticSlayer
A: 

If you don't have the original file, the file size is not clear as it depends on the image format and quality. So what you'd have to do is write the image to a stream (e.g. MemoryStream) and then use the stream's size.

Stefan Schultze