我已经和佳能EDSDK打了一段时间了。我可以成功地获得库来将文件直接保存到磁盘,但是,我无法在内存中获得图像byte[]。每当我尝试将Marshal.Copy() EDSDK转换为byte[]时,总是会遇到以下错误:
AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
下面是我用来尝试获取流的代码变体之一:
private uint downloadImage(IntPtr directoryItem)
{
uint err = EDSDK.EDS_ERR_OK;
IntPtr stream = IntPtr.Zero;
// Get information of the directory item.
EDSDK.EdsDirectoryItemInfo dirItemInfo;
err = EDSDK.EdsGetDirectoryItemInfo(directoryItem, out dirItemInfo);
// Create a file stream for receiving image.
if (err == EDSDK.EDS_ERR_OK)
{
err = EDSDK.EdsCreateMemoryStream(dirItemInfo.Size, out stream);
}
// Fill the stream with the resulting image
if (err == EDSDK.EDS_ERR_OK)
{
err = EDSDK.EdsDownload(directoryItem, dirItemInfo.Size, stream);
}
// Copy the stream to a byte[] and
if (err == EDSDK.EDS_ERR_OK)
{
byte[] buffer = new byte[dirItemInfo.Size];
GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
// The following line is where it blows up...
Marshal.Copy(stream, buffer, 0, (int)dirItemInfo.Size);
// ... Image manipulation, show user, whatever
}
return err;
}断点显示(通过EdsDirectoryItemInfo对象)图像确实在那里,我只是不知道为什么我会得到异常我一直在尝试接受失败的想法,只是从磁盘读取结果映像,这样它就可以很容易地通过CreateFileStream方法编写,但是我真的应该能够在内存中操作这个映像。
有什么想法吗?
更新:我在2.5和2.6版本中都看到了这种行为。
发布于 2009-07-05 08:34:44
我刚刚在谷歌上搜索了EdsCreateMemoryStream和找到一个样本,其中还有另一个从“内存流”获取指针的调用。
IntPtr pointerToBytes;
EDSDKLib.EDSDK.EdsGetPointer(stream, out pointerToBytes);然后可以使用pointerToBytes作为在Marshal.Copy中读取的源。
因此,我猜想您目前正在做的是从stream指向的一些小控制结构的地址开始复制大量字节,因此您正在读取该结构的末尾。
编辑:顺便说一下,你的代码看起来好像有人告诉你,你应该只有一个返回语句!这是关于Fortran和C等语言的老建议,在现代语言中没有意义。如果每次发生故障时立即返回错误代码,代码将更加清晰(至少在本例中是如此):
if ((err = EDSDK.EdsBlahBlah(...)) != EDSDK.EDS_ERR_OK)
return err;(更好的方法是抛出一个包含错误代码的特定异常类,并抛出一个字符串来解释您要做的事情。)
发布于 2012-09-27 00:49:46
我意识到这是一个旧的帖子,但是这是一个从内存流下载的完整的C#片段。它可能对其他人有用。相机需要设置为EDSDK.EdsSaveTo.Host或EDSDK.EdsSaveTo.Both
uint error = EDSDK.EDS_ERR_OK;
IntPtr stream = IntPtr.Zero;
EDSDK.EdsDirectoryItemInfo directoryItemInfo;
error = EDSDK.EdsGetDirectoryItemInfo(this.DirectoryItem, out directoryItemInfo);
//create a file stream to accept the image
if (error == EDSDK.EDS_ERR_OK)
{
error = EDSDK.EdsCreateMemoryStream(directoryItemInfo.Size, out stream);
}
//down load image
if (error == EDSDK.EDS_ERR_OK)
{
error = EDSDK.EdsDownload(this.DirectoryItem, directoryItemInfo.Size, stream);
}
//complete download
if (error == EDSDK.EDS_ERR_OK)
{
error = EDSDK.EdsDownloadComplete(this.DirectoryItem);
}
//convert to memory stream
IntPtr pointer; //pointer to image stream
EDSDK.EdsGetPointer(stream, out pointer);
uint length = 0;
EDSDK.EdsGetLength(stream, out length);
byte[] bytes = new byte[length];
//Move from unmanaged to managed code.
Marshal.Copy(pointer, bytes, 0, bytes.Length);
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(bytes);
Image image = System.Drawing.Image.FromStream(memoryStream);
if (pointer != IntPtr.Zero)
{
EDSDK.EdsRelease(pointer);
pointer = IntPtr.Zero;
}
if (this.DirectoryItem != IntPtr.Zero)
{
EDSDK.EdsRelease(this.DirectoryItem);
this.DirectoryItem = IntPtr.Zero;
}
if (stream != IntPtr.Zero)
{
EDSDK.EdsRelease(stream);
stream = IntPtr.Zero;
}https://stackoverflow.com/questions/1083446
复制相似问题