将图像(byte [] BMP)保存到Ole Photo Column

时间:2014-02-04 03:49:11

标签: c# ms-access bytearray ole

这是我之前question的扩展。我基本上是:

  1. 从访问数据库中检索OleImage

  2. stripping oleheader

  3. 裁剪并调整图像大小

  4. 将图像保存回数据库(被困在这里)

  5. 所以我已经完成了第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。

    1. 是否可以简单地将原始的Ole标题追加到bmp和 更新记录?

    2. 我可以在访问图片框控件上进行某种切换 翻转让它识别bmp字节数组? (我知道这是一个很长的镜头 而且我真的不想弄乱访问代码,因为它超级老了)

    3. 如果以上的答案都是否定的,那么将它们转换回来 Ole图像,而无需shell访问应用程序?

    4. @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)的原因是我已经得到了大量的内存压力错误,因为我正在调整大小的图像是如此之大,我正在运行它们通过几种方法找到一张脸,在脸上裁剪,然后去饱和图像。显然我可以把它分解成序列,但在某个时刻我想要一些我可以在合理数量的传球中运行的东西。这是我对shelling访问的关注.--------- 回到问题

      编辑2

      Microsoft Support Article通过另一个question

      找到了这篇文章

      “的陷阱

      此测试不适用于随Access和SQL Server一起分发的示例Northwind数据库的Employees表中的Photo列。存储在“照片”列中的位图图像使用Visual Basic 6.0 OLE容器控件创建的标题信息进行包装。

      如果需要使用Access数据库来测试此代码,则需要在Access表中创建类型为OLE Object的列,并使用System.Data.OleDb命名空间和Microsoft Jet 4.0 Provider代替System.Data.SqlClient命名空间。“

      这暗示使用“System.Data.OleDb”命名空间。是否有与Ole Photo类型对应的特定数据类型?

2 个答案:

答案 0 :(得分:1)

在简短的聊天之后,似乎Access.Application(自动化)方法概述here(在此问题中出现稍微修改过的代码版本)可能是可行的。根据我的计时测试处理75,000条记录可能需要几个小时(在我最老的机器上,1000条记录只需不到3.5分钟),但这几乎肯定比研究,编写和调试本机C#代码所需的时间快得多。直接进行“OLE包装”。

Image illustrating steps needed to be take in access to make the code work

答案 1 :(得分:0)

'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.