Skip to content

Instantly share code, notes, and snippets.

@jstedfast
Last active December 15, 2015 12:09
Show Gist options
  • Save jstedfast/5258318 to your computer and use it in GitHub Desktop.
Save jstedfast/5258318 to your computer and use it in GitHub Desktop.
public static ImageInfo ReadPng (string fileName)
{
int w, h;
if (GetPngImageSize (fileName, out w, out h))
return new ImageInfo { FileName = fileName, Width = w, Height = h };
return new ImageInfo ();
}
public static ImageInfo ReadJpg (string fileName)
{
int w, h;
if (GetJpgImageSize (fileName, out w, out h))
return new ImageInfo { FileName = fileName, Width = w, Height = h };
return new ImageInfo ();
}
public static ImageInfo Read (string fileName)
{
ImageInfo info = ReadPng (fileName);
if (info.FileName == null)
info = ReadJpg (fileName);
return info;
}
static int ReadInt (BinaryReader reader)
{
int result = 0;
result += (int)reader.ReadByte () << 24;
result += (int)reader.ReadByte () << 16;
result += (int)reader.ReadByte () << 8;
result += (int)reader.ReadByte ();
return result;
}
static bool GetPngImageSize (string fileName, out int width, out int height, bool tryReverting = true)
{
// PNG file format specification can be found at: http://www.w3.org/TR/PNG
BinaryReader reader = null;
try {
reader = new BinaryReader (File.OpenRead (fileName));
var pngHeader = reader.ReadBytes (8);
// Check for valid PNG header.
if (pngHeader[0] != 137 ||
pngHeader[1] != 80 || pngHeader[2] != 78 || pngHeader [3] != 71 ||
pngHeader [4] != 13 || pngHeader [5] != 10 || pngHeader [6] != 26 || pngHeader [7] != 10)
throw new IOException ("File has no valid PNG header.");
// First chunk is always the IHDR header chunk
reader.ReadBytes (4); // skip chunk size
var ihdrID = reader.ReadBytes (4);
if (ihdrID[0] == 73 && ihdrID[1] == 72 && ihdrID[2] == 68 && ihdrID[3] == 82) {
width = ReadInt (reader);
height = ReadInt (reader);
return true;
}
if (tryReverting) {
// Assumed to be an iOS app at this point, which means pngcrush may have made this file unreadable...
var pngcrush = AppleSdkSettings.DeveloperRoot.Combine ("Platforms", "iPhoneOS.platform", "Developer", "usr", "bin", "pngcrush");
if (File.Exists (pngcrush)) {
var reverted = System.IO.Path.GetTempFileName ();
var args = new ProcessArgumentBuilder ();
args.Add ("-revert-iphone-optimizations");
args.AddQuoted (fileName);
args.AddQuoted (reverted);
var output = new StringWriter ();
MonoDevelop.Core.Runtime.ProcessService.StartProcess (pngcrush, args.ToString (), "", output, output, null).WaitForExit ();
bool success = GetPngImageSize (reverted, out width, out height, false);
File.Delete (reverted);
return success;
}
}
throw new IOException ("IHDR missing or corrupt.");
} catch (Exception e) {
LoggingService.LogError ("Error while getting png image size of: " + fileName, e);
width = height = -1;
return false;
} finally {
if (reader != null)
reader.Close ();
}
}
static bool GetJpgImageSize (string filename, out int width, out int height)
{
try {
var type = Pixbuf.GetFileInfo (filename, out width, out height);
return type != null && type.Name == "jpeg";
} catch {
width = height = -1;
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment