转换访问图像OLE对象在C#中的原始图像的字节数组 [英] Convert Access image OLE Object into raw image byte array in C#

查看:369
本文介绍了转换访问图像OLE对象在C#中的原始图像的字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法得到答案一起为我的真正的问题<一href=\"http://stackoverflow.com/questions/19681500/invalid-parameter-when-retrieving-image-from-db\">Invalid从数据库中检索的图像参数时这样伊马一块一块试试。
在C#和MS Access与Visual Studio 2012的工作2010年我的解决方案是一个应用程序的非Web相关的。

I can't seem to get an answer all together for my real issue Invalid parameter when retrieving image from DB So Imma try piece by piece. Working with Visual Studio 2012 in C# and MS Access 2010. My solution is an app non-web related.

我不知道这个部分所以在这里我的问题是关于如何正确获取的图像的的 OLE对象的是在行从查询到的字节数组(的字节[] 的),因为它肯定不是我如何与下面code这样做。
我说的是该行的行[FOTO]

I'm not sure about this part so here my question is on how to correctly get the image of an OLE Object that is in a row from a query into a byte array (byte[]), because certainly it isn't how I'm doing it with the following code. The row I'm talking about is 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);
                    }    
                }

该方法GetImageBytesFromOLEField可以发现<一个href=\"http://blogs.msdn.com/b/pranab/archive/2008/07/15/removing-ole-header-from-images-stored-in-ms-access-db-as-ole-object.aspx\"相对=nofollow>此处。这是给我这是关于索引的长度在该行的误差字符串strVTemp = strTemp.Substring(0,300);

The method GetImageBytesFromOLEField can be found here. The error that it's giving me it's about the length of the index at the line string strVTemp = strTemp.Substring(0, 300);

同样,这里的主要问题是如何打开的 OLE对象的在的DataRow行[FOTO] 在成字节[] 以然后在该方法中使用。

Again, main question here is how to turn the OLE Object in the DataRow row["FOTO"] into byte[] to then use in that method.

推荐答案

这里的问题是,嵌入图像不是一个简单的 BMP JPEG 。这是一个

The problem here is that the imbedded image was not a simple BMP or JPEG. It was a

Microsoft Word图片

和OLE头信息比原来的 GetImageBytesFromOLEField() code的300字节窗口大得多。 (也就是说,扫描300个字节,它只是放弃了与无法确定头的大小...后)。

and the OLE header information was considerably larger than the 300 byte window of the original GetImageBytesFromOLEField() code. (That is, after scanning 300 bytes it just gave up with "Unable to determine header size...".)

以下是code在自己的类的更新版本。走马测试包括所提供的 Microsoft Word图片,一个简单的 BMP ,和一个简单的 JPEG

The following is an updated version of that code in its own class. Cursory testing included the supplied Microsoft Word Picture, a simple BMP, and a simple 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 = "\u0089PNG\r\n\u001a\n"
            imageSignatures.Add(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A });
            // JPG_ID_BLOCK = "\u00FF\u00D8\u00FF"
            imageSignatures.Add(new byte[] { 0xFF, 0xD8, 0xFF });
            // GIF_ID_BLOCK = "GIF8"
            imageSignatures.Add(new byte[] { 0x47, 0x49, 0x46, 0x38 });
            // TIFF_ID_BLOCK = "II*\u0000"
            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: http://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;
        }
    }
}

这篇关于转换访问图像OLE对象在C#中的原始图像的字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆