不使用 Drawing.Image 获取图像宽度/高度

发布于 2024-08-22 00:28:59 字数 173 浏览 4 评论 0原文

我知道这听起来很奇怪。我有一个照片库,可将图像信息(网址、名称、修改日期...)从硬盘保存到内存集合中。

问题是我想将图像宽度/高度存储到该集合中。我可以使用 Drawing.Image 类获取每个文件。但考虑到图库可能会变得相当大,为每个文件创建一个新的图像对象将显着降低性能。

有什么想法吗?谢谢

I know it sounds weird. I have a photo gallery that saves image info(url, name, date modified...) from the hard disk into an in memory collection.

The thing is i want to have the image width/height stored into that collection. I can get it for each file using the Drawing.Image class. But considering the gallery can get quite big, creating a new image object for each file is going to reduce performance significantly.

any ideas?, thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微凉徒眸意 2024-08-29 00:28:59

我已经很长时间没有对图像文件进行原始处理了,但我认为使用最常见的格式(GIF、BMP、JPG 等),您可能可以在前几百内找到高度/宽度文件的字节(或更少)。您必须进行一些编码来处理标头信息(可能有大量在线示例),但与将整个图像读入内存相比,它应该会显着加快您的处理速度。

It's been a LONG time since I did raw processing of image files, but I would think that with the most common formats (GIF, BMP, JPG, etc...), you can probably find the height/width within the first few hundred bytes (or less) of the file. You'd have to do some coding to process the header information (probably tons of examples online), but it should speed up your process significantly vs. reading the entire image into memory.

云归处 2024-08-29 00:28:59

像 Windows 资源管理器一样从图像中提取信息。

看一下这里:

或这里:

或者您也可以使用以下内容读取扩展文件属性:

public static void Main(string[] args)
{
    List<string> arrHeaders = new List<string>();    
    Shell32.Shell shell = new Shell32.Shell();
    Shell32.Folder objFolder = shell.NameSpace(@"C:\temp\testprop");

    for( int i = 0; i < short.MaxValue; i++) {
        string header = objFolder.GetDetailsOf(null, i);
        if (String.IsNullOrEmpty(header)) break;
        arrHeaders.Add(header);
    }

    foreach(Shell32.FolderItem2 item in objFolder.Items()) {
        for (int i = 0; i < arrHeaders.Count; i++) {
            Console.WriteLine("{0}\t{1}: {2}", i, 
                arrHeaders[i], objFolder.GetDetailsOf(item, i));
        }
    }
}

Extract information from images like Windows Explorer does.

Take a look here:

or here:

Or you can also read the extended file properties with the following:

public static void Main(string[] args)
{
    List<string> arrHeaders = new List<string>();    
    Shell32.Shell shell = new Shell32.Shell();
    Shell32.Folder objFolder = shell.NameSpace(@"C:\temp\testprop");

    for( int i = 0; i < short.MaxValue; i++) {
        string header = objFolder.GetDetailsOf(null, i);
        if (String.IsNullOrEmpty(header)) break;
        arrHeaders.Add(header);
    }

    foreach(Shell32.FolderItem2 item in objFolder.Items()) {
        for (int i = 0; i < arrHeaders.Count; i++) {
            Console.WriteLine("{0}\t{1}: {2}", i, 
                arrHeaders[i], objFolder.GetDetailsOf(item, i));
        }
    }
}
从此见与不见 2024-08-29 00:28:59

如果您想获取该信息而不实际为每个图像构建 Image 对象实例,则需要编写代码来读取每个单独的图像文件并提取信息。虽然当然有可能,但您会发现它有些复杂。首先,您需要读取文件前几个字节的代码来确定文件中包含什么类型的图像(.bmp、.gif、.png、.jpg 等),然后您需要用于提取您支持的每种图像类型的信息的特殊代码。

虽然上面的代码几乎肯定比加载整个图像、提取相关数据然后销毁图像的代码快,但我不能说快多少。执行时间的节省很可能不足以证明您在此类解决方案中投入的时间是合理的。

如果我编写这个程序,我的第一个剪辑将按照 ChrisF 的建议进行,并编写如下内容:

foreach (string filename in ImageFilenames)
{
    using (Bitmap bmp = new Bitmap(filename))
    {
        // extract and store needed information
    }
}

一旦您开始工作,您就可以决定它是否足够快以达到您的目的。如果不是,那么我建议您进行一个测试,修改该循环以通过从每个文件中读取第一个千字节左右来模拟提取信息:

foreach (string filename in ImageFilenames)
{
    using (File f = File.OpenRead(filename))
    {
        // read the first 1K from the file
        // store some placeholder data for height/width
    }
}

如果其执行速度明显快于第一个,那么可能值得研究执行您的操作的可能性自己的图像头解析。但请注意,您正在打开一大堆蠕虫。图像头解析可能会非常复杂。

If you want to get that information without actually constructing an Image object instance for each image, you'll need to write code that reads each individual image file and extracts the information. Although certainly possible, you'll find it somewhat involved. First, you'll need code that reads the first few bytes of the file to determine what type of image (.bmp, .gif, .png, .jpg, etc.) is contained in the file, and then you'll need special code to extract the information for each image type that you support.

Whereas the above would almost certainly be faster than code that loads the entire image, extracts the relevant data, and then destroys the image, I can't say how much faster. It's quite possible that the execution time savings doesn't justify the amount of time you'll put into such a solution.

Were I writing this program, my first cut would do as ChrisF suggested, and write something like:

foreach (string filename in ImageFilenames)
{
    using (Bitmap bmp = new Bitmap(filename))
    {
        // extract and store needed information
    }
}

Once you get that working, you can decide if it's fast enough for your purposes. If it's not, then I would suggest a test where you modify that loop to simulate extracting the information by reading the first kilobyte or so from each file:

foreach (string filename in ImageFilenames)
{
    using (File f = File.OpenRead(filename))
    {
        // read the first 1K from the file
        // store some placeholder data for height/width
    }
}

If that performs significantly faster than the first, then it's probably worth investigating the possibility of doing your own image header parsing. Be aware, though, that you're opening a big can of worms. Image header parsing can get quite involved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文