将图像 (byte[] BMP) 保存到 Ole Photo 列
Posted
技术标签:
【中文标题】将图像 (byte[] BMP) 保存到 Ole Photo 列【英文标题】:Saving Image (byte[] BMP) to an Ole Photo Column 【发布时间】:2014-02-04 03:49:11 【问题描述】:这是我之前question 的扩展。我基本上是:
从访问数据库中检索 OleImage
stripping oleheader
裁剪图像并调整其大小
将图像保存回数据库(卡在此处)
所以我已经到了第 4 步。最初我希望应用程序代码能够识别 BMP
byte[]
数组。但是将其保存回数据库后:
private void SaveImage(string imgPath, int ID)
var myconn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\SUFDB2006.mdb");
var pic = File.ReadAllBytes(imgPath);
var cmd = new OleDbCommand CommandType = CommandType.Text, CommandText = "UPDATE Contact SET Photo = @p1 WHERE [Contact ID#] = 7707", Connection = myconn ;
myconn.Open();
cmd.Parameters.AddWithValue("@p1", pic);
cmd.ExecuteNonQuery();
myconn.Close();
表单上的图片框无法识别(访问:(上图)。
显然我需要将 bmp 转换回 Oleimage。
是否可以简单地将原始 Ole 标头附加到 bmp 和 更新记录?
访问图片框控件上是否有某种开关,我可以 翻转让它识别 bmp 字节数组? (我知道这是一个长镜头 而且我真的不想弄乱访问代码,因为它超级旧)
如果上述答案是否定的,是否可以将它们转换回 Ole Images 无需外壳访问应用程序?
@GordThompson 有一个answer:
private void OleShellAccessUpdate(string bmp, int Id)
int recordIdToUpdate = 75;
string bmpPath = bmp;
var paths = new System.Collections.Specialized.StringCollection();
paths.Add(bmpPath);
Clipboard.SetFileDropList(paths);
var accApp = new Microsoft.Office.Interop.Access.Application();
accApp.OpenCurrentDatabase(@"E:\SUFDB2006.mdb");
accApp.DoCmd.OpenForm("Contact Entry", Microsoft.Office.Interop.Access.AcFormView.acNormal, null, "[Contact ID#]=" + recordIdToUpdate);
accApp.DoCmd.RunCommand(Microsoft.Office.Interop.Access.AcCommand.acCmdPaste);
accApp.DoCmd.Close(Microsoft.Office.Interop.Access.AcObjectType.acForm, "Photo", Microsoft.Office.Interop.Access.AcCloseSave.acSaveNo);
accApp.CloseCurrentDatabase();
accApp.Quit();
this.Close();
但是考虑到我正在处理的记录量,在这种情况下,这并不是一个实际的解决方案。我需要一种方法来做到这一点,而无需对应用程序进行炮击。所以我有几个问题:
编辑 - 针对 Gords 评论
我尝试了上面的代码,但没有成功。我说太多记录(75,000 条)的原因是我已经收到了内存压力错误,因为我正在调整大小的图像太大了,我正在通过几种方法运行它们以找到一张脸,裁剪脸部,然后去饱和图像。显然我可以把它分解成序列,但在某个时候我想要一些我可以在合理数量的传球中运行的东西。这是我对炮击访问的担忧。--------- 返回问题
编辑 2
Microsoft Support Article通过另一个question找到这篇文章
"陷阱
此测试不适用于随 Access 和 SQL Server 分发的示例 Northwind 数据库的员工表中的照片列。存储在 Photo 列中的位图图像使用 Visual Basic 6.0 OLE Container 控件创建的标题信息进行包装。
如果您需要使用 Access 数据库来测试此代码,您需要在 Access 表中创建类型为 OLE 对象的列,并使用带有 Microsoft Jet 4.0 Provider 的 System.Data.OleDb 命名空间来代替System.Data.SqlClient 命名空间。”
这暗示使用“System.Data.OleDb”命名空间。是否有与 Ole Photo 类型对应的特定数据类型?
【问题讨论】:
@puretppc 谢谢,你在那个编辑上打败了我,哈哈 没问题。哦,我的坏。我应该让你先编辑它,但我正在努力争取金徽章,所以如果我看到值得格式化的东西,我会这样做。 @puretpcc 不用担心看起来比我拥有它的方式更好,哈哈 re:“考虑到我正在处理的记录量” - 那会是多少?请记住,使用 this 的改编版来处理 n 图像并不一定意味着您需要启动/停止 Access 进程 n 次。值得一提的是,我那破旧的笔记本在不到 3.5 分钟的时间内更新了 1000 张 OLE 图像。 @GordThompson 我在上面尝试过的代码实际上并不能让它工作(正如我所说的,我最初希望根本不使用 ole,而只是 bmp [ ] 字节数组)。我不熟悉互操作,你能告诉我我做错了什么。表单名称是“联系人条目”,表格是“联系人”,列是“[联系人 ID#]”和“[照片]” 【参考方案1】:经过简短的交谈,似乎here 概述的Access.Application
(自动化)方法(此问题中出现了代码的略微修改版本)毕竟可能是可行的。根据我的计时测试,处理 75,000 条记录可能需要几个小时(在我最旧的机器上,1000 条记录只用了不到 3.5 分钟),但这几乎肯定会比研究、编写和调试本机 C# 代码所需的时间快得多直接做“OLE wrapping”。
【讨论】:
添加的图片说明了我对这个过程的困惑再次感谢您的帮助!【参考方案2】:'SqlConnection objCon = new SqlConnection(con);
objCon.Open();
SqlCommand cmd = new SqlCommand("Studentinsertadmission", objCon);
cmd.Parameters.Add(new SqlParameter("@Studentid",Convert.ToInt32( studentid.Text)));
cmd.Parameters.Add(new SqlParameter("@StudentName", firstname.Text));
cmd.Parameters.Add(new SqlParameter("@Image", image.image ));
cmd.CommandType = CommandType.StoredProcedure;
int rows = cmd.ExecuteNonQuery();
objCon.Close();
MessageBox.Show("Record Inserted Successfully! ");'
Try this it works deppending on the component.
【讨论】:
我认为这不能解决 Ole Header 的问题以上是关于将图像 (byte[] BMP) 保存到 Ole Photo 列的主要内容,如果未能解决你的问题,请参考以下文章