Before calling System.Drawing.Image.FromFile(path)
resolve the path from a URL to an absolute path. You can do this by calling Server.MapPath(path)
.
i.e.
string path = @"~/img/company.png";
path = Server.MapPath(path);
using (System.Drawing.Image image = System.Drawing.Image.FromFile(path))
or simply
string path = @"~/img/company.png";
using (System.Drawing.Image image = System.Drawing.Image.FromFile(Server.MapPath(path)))
More Detailed Explanation
- When dealing with resources on the web, we use URLs.
- The URL
~/img/company.png
says to navigate from the site's root (this is what the tilde (~
) refers to) to the img
subfolder, then to the file company.png
.
- The
System.Drawing.Image
class was not built for URLs, so doesn't know how to handle them. Rather it expects a path for the file system. The reasons it can't understand a URL are:
- it doesn't know what tilde means
- it doesn't know where the site's root is
- even given
path = @"img\company.png"
it would try to find the file based on the working directory rather than the site's root directory. The current working directory is likely to be the location of IIS's executable (c:\Windows\System32\inetsrv\ though I'm not sure / it's probably best not to know as the idea of a working directory doesn't make sense in a web context).
- it has no awareness of virtual paths; so even if the working directory were the same as the site's root and the tilde were missed,
\img\
may sit in an entirely different location on disk to where it comes in the site's structure; perhaps even being mapped to a share on some remote file server).
- Calling
Server.MapPath
resolves this URL to a real path which can be understood by non-web aware functions.
There's a great answer giving a lot more detail and examples on Server.MapPath
here: https://stackoverflow.com/a/27500722/361842