zoukankan      html  css  js  c++  java
  • 从读取Excel文件引申出的问题(下)

    从上一篇的:从读取Excel文件引申出的问题(上)中,对于从Excel文件中抓取的图片读取速度太慢的,问题主要来源于IComObject对象在经过了Copy和Paste后,造成了对内存及各种计算上的消耗后,速度已大大下降鸟。这几天研究来研究去,也没个结果,索性将这个问题再次提起,借众人之力。

    在这一次的实验中,我借助了Marshal类的功能,提取IcomObject对象的指针,通过指针,希望读取Excel文件中图形对象的内容,代码如下:

    代码
    byte[] bytes =null;
    List
    <byte> bs =new List<byte>();
    IntPtr intptr
    = item.GetType().TypeHandle.Value;
    byte b =1;
    int s =0;
    while (b >0) {b = Marshal.ReadByte(intptr, s * Marshal.SizeOf(typeof(IntPtr))); s++;bs.Add(b);}
    bytes
    = bs.ToArray();

    然后 将读取到的对象内容通过流的形式写入文件。

    using (FileStream fs =new FileStream(@"D:\temp\"+ row +".jpg", FileMode.Create, FileAccess.Write))
    {
    fs.Write(bytes,
    0, bytes.Length);
    fs.Flush();
    fs.Close();
    }

    最后发现太失败了,内容是读取出来了,但是基本上只读取了10K的内容,图像是无法显示的。这是什么问题呢?

    本来嘛,希望通过Marshal来获取对象大小的,最后发现无效,抛出了ArgumentException异常:

    int len = Marshal.SizeOf(typeof(Excel.Shape));
    类型“Microsoft.Office.Interop.Excel.Shape”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。

    算了,还是走回老路吧,最后被逼得没办法了,来招狠的,在图像保存格式上下功夫,这次我不再把获取到的Shape强制转换为BitMap对象,因为从DataObject对象中,我们可以获取到剪贴板对象中支持转换的对象格式,如下:

    这下好了,我直接从DataObject对象中获取图片对象,即Image对象,再直接保存,保存的时候会发生一点小问题,即图像格式的问题。

    代码
    DataObject data = (DataObject)Clipboard.GetDataObject();
    Image img
    = data.GetImage();
    img.Save(
    @"D:\temp\aa\"+ row +".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
    Clipboard.Clear();
    // 清除剪贴板内容

    Clipboard.Clear();  //  清除剪贴板内容

    通过对比,发现保存为GIF格式可获取最高压缩级,Bmp为高保真级存储,消耗的内存和时间还真不是一般的多,当然,我选择了中庸方案:Jpeg格式。下面的数据为同一幅18KB的图片在各种格式下的存储大小,即所谓的压缩比了。

    Jpeg:10KB
    Bmp:145KB
    PNG:18KB
    GIF:7KB
    Tiff:29KB

    到最后的完整代码实际上为六行代码。

    代码
    item.Copy();
    DataObject data
    = (DataObject)Clipboard.GetDataObject();
    Image img
    = data.GetImage();
    img.Save(
    @"D:\temp\aa\"+ row +".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
    Clipboard.Clear();
    img.Dispose();

    但是还是那句话,效率上还是上不去,唯一可做的是,通过把图片进行有损压缩,达到一定程度的提高速度,但是这不是最终想的结果,因为Image对象在写入文件时,默认单次写入大小最大为:1KB。不知道还有什么可以提高地方。

  • 相关阅读:
    Shiro理解与总结
    spark教程(14)-共享变量
    Hive 教程(十)-UDF
    multivariate_normal 多元正态分布
    windows 安装 python 踩坑记录
    EM 算法(三)-GMM
    EM 算法(二)-KMeans
    EM 算法(一)-原理
    sklearn-GDBT
    集成学习-Boosting 模型深度串讲
  • 原文地址:https://www.cnblogs.com/viter/p/1644102.html
Copyright © 2011-2022 走看看