Strahan
Member
- Joined
- Mar 28, 2015
- Messages
- 11
- Programming Experience
- 3-5
Hello. I'm working on a wallpaper shuffling program. Everything is going swimmingly, but I ran into a snag. I added the ability when it shuffles to be able to limit the resolution, so it only picks files where the width or height meets or exceeds a set value. As soon as I added that, the whole thing blew up lol. Works fine for directories with only a few files, but it crashes "out of memory" on larger folders. I made a test console app to remove everything from the equation but just the simple act of getting res and I have the same problem.
Results in:
I was getting annoyed, so I tried avoiding the problem by shelling out to MediaInfo. To process the folder still takes forever; 38 seconds. Interestingly, I made a PHP script to dump resolutions and that took only a little over one second...?? I don't really think though bundling PHP with my application is the ideal solution, lol.
Does anyone know a way to parse a lot of files' resolutions in a similarly fast manner in C# directly?
EDIT: I found this interesting. I was thinking, can't I just read the values right from the file? I assume they are in the header of the file. I used a PNG to test, and sure enough, the resolutions are right there as hex values. So I did:
I ran it against my folder; it only took 2.72 seconds Problem is, I don't know if this is reliable. Is it always the same offset? I also need to find it for JPEG as well then. I guess I should Google and look for the header specification for the two formats. Is this a good way to go though?
C#:
static void Main(string[] args) {
foreach (string file in Directory.GetFiles(Environment.CurrentDirectory)) {
using (Image img = Image.FromFile(file)) {
Console.WriteLine("[" + img.Width + "][" + img.Height + "]: " + file);
}
}
}
Results in:
C#:
(..206 prior..)
[1920][1080]: F:\D\Media\Pics\Wallpaper\e7519050a71166d9d24c2a7989afcb40.png
[1920][1080]: F:\D\Media\Pics\Wallpaper\ea21e39bc7982a334dea213d2d8d9a6e.png
[1920][1080]: F:\D\Media\Pics\Wallpaper\ebaa92965dfaf6d424a143630024b5f1.png
Unhandled Exception: OutOfMemoryException.
I was getting annoyed, so I tried avoiding the problem by shelling out to MediaInfo. To process the folder still takes forever; 38 seconds. Interestingly, I made a PHP script to dump resolutions and that took only a little over one second...?? I don't really think though bundling PHP with my application is the ideal solution, lol.
Does anyone know a way to parse a lot of files' resolutions in a similarly fast manner in C# directly?
EDIT: I found this interesting. I was thinking, can't I just read the values right from the file? I assume they are in the header of the file. I used a PNG to test, and sure enough, the resolutions are right there as hex values. So I did:
C#:
static void Main(string[] args) {
foreach (string filePath in Directory.GetFiles(Environment.CurrentDirectory)) {
try {
using (FileStream fileStream = File.OpenRead(filePath)) {
if (fileStream.Length < 24) continue;
byte[] buffer = new byte[24];
int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
int width = Convert.ToInt32(buffer[18].ToString("X") + buffer[19].ToString("X"), 16);
int height = Convert.ToInt32(buffer[22].ToString("X") + buffer[23].ToString("X"), 16);
Console.WriteLine("[" + width + "][" + height + "]: " + Path.GetFileName(filePath));
}
} catch (IOException ex) {
Console.WriteLine("An error occurred while reading the file: {0}", ex.Message);
}
}
}
I ran it against my folder; it only took 2.72 seconds Problem is, I don't know if this is reliable. Is it always the same offset? I also need to find it for JPEG as well then. I guess I should Google and look for the header specification for the two formats. Is this a good way to go though?
Last edited: