ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

将访问图像OLE对象转换为C#中的原始图像字节数组

2019-11-22 15:06:11  阅读:380  来源: 互联网

标签:datarow c ms-access bytearray ms-access-2010


我的真正问题Invalid parameter when retrieving image from DB似乎无法完全得到答案,所以Imma一步一步尝试.
在C#和MS Access 2010中使用Visual Studio2012.我的解决方案是与网络无关的应用程序.

我不确定这部分,所以在这里我的问题是如何正确地将查询中的OLE对象的图像获取到字节数组(byte [])中,因为肯定不是我正在使用以下代码进行操作.
我要说的行是row [“ FOTO”].

                OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [APP_Equipamento_Geral] WHERE COD_ETIQ like '%" + codigo + "%'", l);
                DataSet ds = new DataSet();
                adapter.Fill(ds, "[APP_Equipamento_Geral]");
                string s = ds.Tables["[APP_Equipamento_Geral]"].Columns[16].ColumnName;
                foreach (DataRow row in ds.Tables["[APP_Equipamento_Geral]"].Rows)
                {
                    eq.NSerie = row["N_SERIE"].ToString();
                    eq.NInventario = row["Codigo"].ToString(); 

                    if (row["FOTO"] != DBNull.Value && row["FOTO"] != null)
                    {
                        string str = row["FOTO"].ToString();
                        byte[] b = stringToByteArray(str);
                        byte[] imagebyte = GetImageBytesFromOLEField(b); //Error caught here

                        MemoryStream ms = new MemoryStream();
                        ms.Write(imagebyte, 0, imagebyte.Length);
                    }    
                }

可以找到here方法GetImageBytesFromOLEField.它给我的错误是关于行字符串strVTemp = strTemp.Substring(0,300)处的索引长度.

同样,这里的主要问题是如何将DataRow行[“ FOTO”]中的OLE对象转换为byte [],然后在该方法中使用.

解决方法:

这里的问题是,嵌入的图像不是简单的BMP或JPEG.那是个

Microsoft Word图片

OLE标头信息比原始GetImageBytesFromOLEField()代码的300字节窗口大得多. (也就是说,在扫描300个字节后,它只是放弃了“无法确定标头大小…”.)

以下是该代码在其自己的类中的更新版本.光标测试包括提供的Microsoft Word图片,简单的BMP和简单的JPEG.

using System;
using System.Collections.Generic;
using System.Linq;

namespace OleImageTest
{
    public static class OleImageUnwrap
    {
        public static byte[] GetImageBytesFromOLEField(byte[] oleFieldBytes)
        {
            // adapted from http://blogs.msdn.com/b/pranab/archive/2008/07/15/removing-ole-header-from-images-stored-in-ms-access-db-as-ole-object.aspx

            const int maxNumberOfBytesToSearch = 10000;
            byte[] imageBytes;  // return value

            var imageSignatures = new List<byte[]>();
            // PNG_ID_BLOCK = "\x89PNG\r\n\x1a\n"
            imageSignatures.Add(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A });
            // JPG_ID_BLOCK = "\xFF\xD8\xFF"
            imageSignatures.Add(new byte[] { 0xFF, 0xD8, 0xFF });
            // GIF_ID_BLOCK = "GIF8"
            imageSignatures.Add(new byte[] { 0x47, 0x49, 0x46, 0x38 });
            // TIFF_ID_BLOCK = "II*\x00"
            imageSignatures.Add(new byte[] { 0x49, 0x49, 0x2A, 0x00 });
            // BITMAP_ID_BLOCK = "BM"
            imageSignatures.Add(new byte[] { 0x42, 0x4D });

            int numberOfBytesToSearch = (oleFieldBytes.Count() < maxNumberOfBytesToSearch ? oleFieldBytes.Count() : maxNumberOfBytesToSearch);
            var startingBytes = new byte[numberOfBytesToSearch];
            Array.Copy(oleFieldBytes, startingBytes, numberOfBytesToSearch);

            var positions = new List<int>();
            foreach (byte[] blockSignature in imageSignatures)
            {
                positions = startingBytes.IndexOfSequence(blockSignature, 0);
                if (positions.Count > 0)
                {
                    break;
                }
            }
            int iPos = -1;
            if (positions.Count > 0)
            {
                iPos = positions[0];
            }

            if (iPos == -1)
                throw new Exception("Unable to determine header size for the OLE Object");

            imageBytes = new byte[oleFieldBytes.LongLength - iPos];
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            ms.Write(oleFieldBytes, iPos, oleFieldBytes.Length - iPos);
            imageBytes = ms.ToArray();
            ms.Close();
            ms.Dispose();
            return imageBytes;
        }

        private static List<int> IndexOfSequence(this byte[] buffer, byte[] pattern, int startIndex)
        {
            // ref: https://stackoverflow.com/a/332667/2144390
            List<int> positions = new List<int>();
            int i = Array.IndexOf<byte>(buffer, pattern[0], startIndex);
            while (i >= 0 && i <= buffer.Length - pattern.Length)
            {
                byte[] segment = new byte[pattern.Length];
                Buffer.BlockCopy(buffer, i, segment, 0, pattern.Length);
                if (segment.SequenceEqual<byte>(pattern))
                    positions.Add(i);
                i = Array.IndexOf<byte>(buffer, pattern[0], i + 1);
            }
            return positions;
        }
    }
}

标签:datarow,c,ms-access,bytearray,ms-access-2010
来源: https://codeday.me/bug/20191122/2060775.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有