• 提取超大图片像素数据的方法


    前些日子组长让我做一个检索图片信息的程序,包括图片存储路径、图片大小、修改日期和图片长宽等信息。刚开始我以为很简单,只要做一个遍历特定文件夹下的文件,判断是否为图片文件,如果是的话就将图片的这些信息存入数据库中。用C#做起了很简单吧,只要如下代码就行了

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;

    namespace DirectoryMonitor
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                DoWork();
            }
             public void DoWork()
            {
                List<string> fileList = new List<string>();
                fileList = GetDirectoryFiles("D:\\TUPIAN", fileList);
                CheckNewFiles(fileList);
               
            }
            /// <summary>
            /// 检查所有新增的文件
            /// </summary>
            /// <param name="list">文件列表</param>
            public void CheckNewFiles(List<string> list)
            {
                foreach (string strpath in list)
                {
                    FileInfo file=new FileInfo(strpath);
                    long lenth=file.Length;
                    string size=lenth/(1024*1024)+"MB";
                    DateTime updatetime=file.CreationTime;
                    Bitmap bit=new Bitmap(strpath);

                    string height=bit.Size.Height.ToString();
                    string width=bit.Size.Width.ToString();
                    string path=strpath;
                }
            }
            /// <summary>
            /// 检测文件是否完整(是否复制过程)
            /// 以只读的方式打开
            /// 打开后直接调用文件指针到文件末端
            /// </summary>
            /// <param name="filename">检测的文件全路径</param>
            /// <returns>返回true表示不占用,false相反</returns>
            private bool CheckFileIsCompleteUploaded(string filename)
            {
                bool flag = true;
                FileInfo info = new FileInfo(filename);
                try
                {
                    FileStream stream = info.OpenRead();
                    stream.Seek(info.Length, SeekOrigin.End);
                    stream.Dispose();
                    stream.Close();
                }
                catch (IOException ioex)
                {
                    flag = false;
                }
                return flag;
            }

            /// <summary>
            /// 递归获取文件夹下包含子文件夹的所有文件
            /// </summary>
            /// <param name="path">文件夹路径</param>
            /// <param name="list">获取目录下的文件信息集合</param>
            /// <param name="fullPath">是否获取全路径(选择否只获取文件名称)</param>
            /// <returns>参数list</returns>
            private List<string> GetDirectoryFiles(string path, List<string> list)
            {
                string[] fileNames = Directory.GetFiles(path);
                string[] directories = Directory.GetDirectories(path);
                foreach (string file in fileNames)
                {
                    string a=file.Substring(file.LastIndexOf('.'),file.Length-file.LastIndexOf('.'));
                    if (a == ".jpeg" || a == ".png")
                    list.Add(file);
                }
                if (directories.Length > 0)
                {
                    foreach (string dir in directories)
                    {
                        list = GetDirectoryFiles(dir, list);
                    }
                }
                return list;
            }

            #region 测试代码(函数)

            /// <summary>
            ///
            /// </summary>
            /// <param name="list"></param>
            /// <returns></returns>
            private string getStringFromList(List<string> list)
            {
                string result = "";
                foreach (string str in list)
                {
                    result = result + str + ",\n";
                }
                return result;
            }


            #endregion

       
        }
    }

    但是我做的时候却报错了,因为我所检索的图片时几百兆以上的超大图片,实例化Bitmap的时候出现内存溢出的现象。于是我开始寻找解决的方法。网上也有人遇到类似问题,但找不到解决的方法,很是惆怅。后来我只好从图片的结构入手了,网上看了看图片的结构发现在图片的物理结构的特定位置就是图片的像素信息。这样问题就解决了,不用假装bitmap,直接把像素信息提取出来就行了。下面是几种图片的像素提取方法,使用任何大小的图片:

    jpeg图片:

    for (int i = 0; i < fstream.Length; i++)
                    {
                        if (bts[i] == 0xFF && bts[i + 1] == 0xC0)
                        {
                            h1 = Convert.ToString((bts[i + 5] * 256) + bts[i + 6]);
                            w1 = Convert.ToString((bts[i + 7] * 256) + bts[i + 8]);
                            break;
                        }
                    }

    bmp图片:

    w1 = Convert.ToString((bts[21] * 256*256*256) +(bts[20] * 256*256)+(bts[19] * 256)+bts[18]);
                    h1 = Convert.ToString((bts[25] * 256 * 256 * 256) + (bts[24] * 256 * 256) + (bts[23] * 256) + bts[22]);

    png图片:

    w1 = Convert.ToString((bts[16] * 256 * 256 * 256) + (bts[17] * 256 * 256) + (bts[18] * 256) + bts[19]);
                    h1 = Convert.ToString((bts[20] * 256 * 256 * 256) + (bts[21] * 256 * 256) + (bts[22] * 256) + bts[23]);

    bts是图片的比特率数组,w1为图片宽度,h1为图片高度。

  • 相关阅读:
    24. orcle创建备份表
    23. oralce11g导出dmp然后导入Oracle10g
    模板
    日记集
    Outlook 2013 电子邮件账户设置备份与恢复
    Firefox恢复书签
    Windows 7 Professional安装多语言包
    CentOS下成功修复了Windows的grub引导
    CentOS 7修复MBR和GRUB
    从移动硬盘开机,引导VHD(Win10)
  • 原文地址:https://www.cnblogs.com/cnzryblog/p/2383996.html
Copyright © 2020-2023  润新知