我有一个名为FPN = "c:\ggs\ggs Access\images\members\1.jpg "
的文件。
我正在尝试获取图像 1.jpg
的尺寸,并且在加载之前我想检查图像尺寸是否有效。
我有一个名为FPN = "c:\ggs\ggs Access\images\members\1.jpg "
的文件。
我正在尝试获取图像 1.jpg
的尺寸,并且在加载之前我想检查图像尺寸是否有效。
System.Drawing.Image img = System.Drawing.Image.FromFile(@"c:\ggs\ggs Access\images\members\1.jpg");
MessageBox.Show("Width: " + img.Width + ", Height: " + img.Height);
Image.FromStream
方法,这样可以避免将整个文件加载到内存中(更快),请参考 https://www.roelvanlisdonk.nl/2012/02/28/fastest-way-to-read-dimensions-from-a-picture-image-file-in-c/。 - drzausWpf类System.Windows.Media.Imaging.BitmapDecoder
无法读取整个文件,只能读取元数据。
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;
}
更新 2019-07-07
处理 exif
格式的图片会稍微复杂一些。由于某些原因,iPhone 保存的图像是旋转的,为了补偿这一点,它们还设置了“在显示之前旋转此图像”exif
标志。
GIF 格式也是相当复杂的。可能没有任何一帧具有完整的 GIF 尺寸,你必须从偏移量和帧大小中聚合它。
所以我使用了 ImageProcessor ,它可以为我解决所有问题。但我从未检查过它是否完全读取了整个文件,因为有些浏览器不支持 exif
,我必须另存一个旋转版本。
using (var imageFactory = new ImageFactory())
{
imageFactory
.Load(stream)
.AutoRotate(); //takes care of ex-if
var height = imageFactory.Image.Height,
var width = imageFactory.Image.Width
}
ImageProcessor
可以访问 https://imageprocessor.org/imageprocessor/imagefactory/#example,而 Getting Started
中有 Install Via Nuget
部分。 - Atomosk针对 .NET Core 用户和任何不想使用第三方库(并且像我一样阅读规范并保持简单性)的人,这里是 JPEG 尺寸的解决方案:
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();
}
}
我为想要改进渐进DCT代码的人留下了一个空间:
if (Data[nIndex] == 0xC2)
很遗憾,System.Drawing
和ImageProcessor
仅支持Windows平台,因为它们是GDI(图形设备接口)的简单包装,而GDI是非常古老的Win32(Windows)非托管绘图API。
相反,只需从NuGet安装SixLabors / ImageSharp 库。以下是如何使用它获取大小的方法:
using (var image = SixLabors.ImageSharp.Image.Load("image-path."))
{
var width = image.Width;
var height = image.Height;
}