How to get the the dimensions of an image file?
Asked Answered
P

5

78

I have a file called FPN = "c:\ggs\ggs Access\images\members\1.jpg "

I'm trying to get the dimension of image 1.jpg, and I'd like to check whether image dimension is valid or not before loading.

Pain answered 23/6, 2011 at 14:45 Comment(1)
No image formats that I know of can have dimensions of 0 pixels...Lhary
E
152
System.Drawing.Image img = System.Drawing.Image.FromFile(@"c:\ggs\ggs Access\images\members\1.jpg");
MessageBox.Show("Width: " + img.Width + ", Height: " + img.Height);
Exclusive answered 23/6, 2011 at 14:47 Comment(7)
@User1: You should edit your question to be more clear as to the meaning of "size".Ether
This would work in terms of working out the size of the image, but if the file is not a valid image file it will throw an exception on the first line rather than the file having 0 height or width. Not sure why the OP thinks that checking if the dimensions of the image are 0 by 0 is an appropriate way to check for a valid image file.Villegas
it throws an excpetion saying that out of memoryPain
Depending on the image sizes you may be better off storing them in a byte array.Exclusive
is it possible to use a uri as a paremeter for FromFile()?Sukkah
@Pain consider Image.FromStream so you might avoid loading the whole file into memory (and faster) -- see roelvanlisdonk.nl/2012/02/28/…Alkmaar
For .net core nuget System.Drawing.Common re: hanselman.com/blog/HowDoYouUseSystemDrawingInNETCore.aspxManion
G
52

Wpf class System.Windows.Media.Imaging.BitmapDecoder doesn't read whole file, just metadata.

using(var imageStream = File.OpenRead("file"))
{
    var decoder = BitmapDecoder.Create(imageStream, BitmapCreateOptions.IgnoreColorProfile,
        BitmapCacheOption.Default);
    var height = decoder.Frames[0].PixelHeight;
    var width = decoder.Frames[0].PixelWidth;
}

Update 2019-07-07 Dealing with exif'ed images is a little bit more complicated. For some reasons iphones save a rotated image and to compensate they also set "rotate this image before displaying" exif flag as such.

Gif is also a pretty complicated format. It is possible that no frame has full gif size, you have to aggregate it from offsets and frames sizes.

So I used ImageProcessor instead, which deals with all the problems for me. Never checked if it reads the whole file though, because some browsers have no exif support and I had to save a rotated version anyway.

using (var imageFactory = new ImageFactory())
{
    imageFactory
        .Load(stream)
        .AutoRotate(); //takes care of ex-if
    var height = imageFactory.Image.Height,
    var width = imageFactory.Image.Width
}
Giannini answered 27/6, 2016 at 4:15 Comment(4)
This should be the top answer because it actually answers the question.Peggiepeggir
@person27 Thanks for comment, I've totaly forgot about that answer by the time QA had fed some nasty images to my code. Now answer is updated.Giannini
The ImageProcessor site does not list how to use...nor does the Nuget Package page to install. Am I missing something?Prosody
@ΩmegaMan There is 3 links on the top, clicking ImageProcessor gives me imageprocessor.org/imageprocessor/imagefactory/#example and Getting Started has Install Via Nuget section.Giannini
E
4

Unfortunately, System.Drawing and ImageProcessor are supported only on the Windows platform because they are a thin wrapper over GDI (Graphics Device Interface) which is very old Win32 (Windows) unmanaged drawing APIs.

Instead, just install the SixLabors/ImageSharp library from NuGet. And here is how you can get size with it:

using (var image = SixLabors.ImageSharp.Image.Load("image-path."))
{
    var width = image.Width;
    var height = image.Height;
}
Eelgrass answered 24/4, 2022 at 9:43 Comment(1)
Seems their license require to purchase a license when using in commercial projects.Mussel
C
4

For .NET Core users and anyone who don't want to use 3rd parity libraries (and like me read the specifications and keep things simple), here is solution for JPEG dimensions:

public class JPEGPicture
{
  private byte[] data;
  private ushort m_width;
  private ushort m_height;

  public byte[] Data { get => data; set => data = value; }
  public ushort Width { get => m_width; set => m_width = value; }
  public ushort Height { get => m_height; set => m_height = value; }
    
  public void GetJPEGSize()
  {
    ushort height = 0;
    ushort width = 0;
    for (int nIndex = 0; nIndex < Data.Length; nIndex++)
    {
      if (Data[nIndex] == 0xFF)
      {
        nIndex++;
        if (nIndex < Data.Length)
        {
          /*
              0xFF, 0xC0,             // SOF0 segement
              0x00, 0x11,             // length of segment depends on the number of components
              0x08,                   // bits per pixel
              0x00, 0x95,             // image height
              0x00, 0xE3,             // image width
              0x03,                   // number of components (should be 1 or 3)
              0x01, 0x22, 0x00,       // 0x01=Y component, 0x22=sampling factor, quantization table number
              0x02, 0x11, 0x01,       // 0x02=Cb component, ...
              0x03, 0x11, 0x01        // 0x03=Cr component, ...
          */
          if (Data[nIndex] == 0xC0)
          {
            Console.WriteLine("0xC0 information:"); // Start Of Frame (baseline DCT)
            nIndex+=4;
            if (nIndex < Data.Length-1)
            {
              // 2 bytes for height
              height = BitConverter.ToUInt16(new byte[2] { Data[++nIndex], Data[nIndex-1] }, 0);
              Console.WriteLine("height = " + height);
            }
            nIndex++;
            if (nIndex < Data.Length - 1)
            {
              // 2 bytes for width
              width = BitConverter.ToUInt16(new byte[2] { Data[++nIndex], Data[nIndex-1] }, 0);
              Console.WriteLine("width = " + width);
            }
          }
        }
      }
    }
    if (height != 0)
      Height = height;
    if (width != 0)
      Width = width;
  }

  public byte[] ImageToByteArray(string ImageName)
  {
    FileStream fs = new FileStream(ImageName, FileMode.Open, FileAccess.Read);
    byte[] ba = new byte[fs.Length];
    fs.Read(ba, 0, Convert.ToInt32(fs.Length));
    fs.Close();

    return ba;
   }
 }

class Program
{
  static void Main(string[] args)
  {
    JPEGPicture pic = new JPEGPicture();
    pic.Data = pic.imageToByteArray("C:\\Test.jpg");
    pic.GetJPEGSize();
  }
}
    

I leave a space for anyone who wants to improve the code for progressive DCT:

if (Data[nIndex] == 0xC2)
Covenantee answered 2/8, 2022 at 13:51 Comment(0)
S
1

Updated for newer versions of .NET

System.Drawing.Common is only supported on Windows making it a poor choice to work with images going forward. ImageSharp is not free for commercial use as of 13/12/2023.

Recommendation: SkiaSharp

SkiaSharp, an MIT Licensed API wrapper around Skia an open source 2D graphics library which provides common APIs that work across a variety of hardware and software platforms.

Getting Image Information with SkiaSharp

IFormFile file; //Get your File
Using var stream = file.OpenReadStream();

var fileHeader = SkiaSharp.SKBitmap.DecodeBounds(stream);
if (fileHeader.IsEmpty) 
  {
     // Handle failed decoding here
  }

var height = fileHeader.Height;
var width = fileHeader.Width;

// Use height and width here

Learn more about working with images using SkiaSharp

Sleepless answered 13/12, 2023 at 16:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.