puede - Convertir Objeto OLE de imagen de acceso en matriz de bytes de imagen sin formato en C#
no se puede convertir de string a byte (1)
El problema aquí es que la imagen incrustada no era una simple BMP
o JPEG
. Era un
Microsoft Word Picture
y la información del encabezado OLE era considerablemente más grande que la ventana de 300 bytes del código original GetImageBytesFromOLEField()
. (Es decir, después de escanear 300 bytes, simplemente se dio por vencido con "No se puede determinar el tamaño del encabezado ...").
La siguiente es una versión actualizada de ese código en su propia clase. Las pruebas de certificación incluyeron la imagen de Microsoft Word Picture
suministrada, un BMP
simple y un JPEG
simple.
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: 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;
}
}
}
Parece que no puedo obtener una respuesta todos juntos para mi problema real. Parámetro no válido al recuperar la imagen de la base de datos. Inma intentarlo pieza por pieza. Trabajando con Visual Studio 2012 en C # y MS Access 2010. Mi solución es una aplicación no relacionada con la web.
No estoy seguro acerca de esta parte, así que aquí mi pregunta es cómo obtener correctamente la imagen de un Objeto OLE que está en una fila de una consulta en una matriz de bytes ( byte [] ), porque ciertamente no es como yo Lo estoy haciendo con el siguiente código. La fila de la que estoy hablando es 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);
}
}
El método GetImageBytesFromOLEField se puede encontrar aquí . El error que me está dando se trata de la longitud del índice en la cadena de líneas strVTemp = strTemp.Substring (0, 300);
Nuevamente, la pregunta principal aquí es cómo convertir el Objeto OLE en la fila DataRow ["FOTO"] en byte [] para luego usarlo en ese método.