pour une raison inconnue, au lieu d'aller au lit, je suis allé travailler à ce sujet.
Voici un code qui résout ce problème avec des exigences de stockage minimales.
void Main()
{
var [email protected]"path\to\my.jpg";
var bytes=File.ReadAllBytes(filePath);
var dimensions=GetJpegDimensions(bytes);
//or
//var dimensions=GetJpegDimensions(filePath);
Console.WriteLine(dimensions);
}
public static Dimensions GetJpegDimensions(byte[] bytes)
{
using(var ms=new MemoryStream(bytes))
{
return GetJpegDimensions(ms);
}
}
public static Dimensions GetJpegDimensions(string filePath)
{
using(var fs=File.OpenRead(filePath))
{
return GetJpegDimensions(fs);
}
}
public static Dimensions GetJpegDimensions(Stream fs)
{
if(!fs.CanSeek) throw new ArgumentException("Stream must be seekable");
long blockStart;
var buf = new byte[4];
fs.Read(buf, 0, 4);
if(buf.SequenceEqual(new byte[]{0xff, 0xd8, 0xff, 0xe0}))
{
blockStart = fs.Position;
fs.Read(buf, 0, 2);
var blockLength = ((buf[0] << 8) + buf[1]);
fs.Read(buf, 0, 4);
if(Encoding.ASCII.GetString(buf, 0, 4) == "JFIF"
&& fs.ReadByte() == 0)
{
blockStart += blockLength;
while(blockStart < fs.Length)
{
fs.Position = blockStart;
fs.Read(buf, 0, 4);
blockLength = ((buf[2] << 8) + buf[3]);
if(blockLength >= 7 && buf[0] == 0xff && buf[1] == 0xc0)
{
fs.Position += 1;
fs.Read(buf, 0, 4);
var height = (buf[0] << 8) + buf[1];
var width = (buf[2] << 8) + buf[3];
return new Dimensions(width, height);
}
blockStart += blockLength + 2;
}
}
}
return null;
}
public class Dimensions
{
private readonly int width;
private readonly int height;
public Dimensions(int width, int height)
{
this.width = width;
this.height = height;
}
public int Width
{
get{return width;}
}
public int Height
{
get{return height;}
}
public override string ToString()
{
return string.Format("width:{0}, height:{1}", Width, Height);
}
}
+1 Je suppose que c'est ce que cela signifie d'aller au-delà de fournir une réponse! – BrokenGlass
J'ai essayé ceci, mais la séquence s'est terminée avec 0xe1 au lieu de 0xe0, et le codage ASCII est sorti comme EXIF. Je suppose que c'est un type différent d'image JPEG, mais cela signifie que cette solution ne fonctionne pas pour toutes les images JPEG. – Grungondola
@Grungondola Vous avez raison ... il y a toute une série de fichiers '.jpg' qui ne fonctionneront pas avec le code ci-dessus. Après des recherches approfondies, je peux dire que de loin la meilleure façon d'extraire des métadonnées d'image est avec [imagemagick] (http://www.imagemagick.org/script/binary-releases.php) ... Pour fournir le meilleur isolement possible le processus d'hébergement, nous appelons le 'magick.exe identifier 'autonome avec' System.Diagnostics.Process' et analysons les méta-données de la sortie standard du processus. Assez à l'épreuve des balles. – spender