我嘗試使用 openfiledialog 將圖片添加到影像串列中,然后將其保存在我的 Ms Access 資料庫中,并以另一種形式呼叫它,通過使用計時器控制元件在圖片框中滑動顯示它們,但是當我嘗試使用打開檔案添加圖片時對話框我收到此錯誤 System.Drawing.dll 中發生“System.OutOfMemoryException”型別的未處理例外附加資訊:記憶體不足。
這是我的代碼
private void btnPicAdd_Click(object sender, EventArgs e)
{
ofdTargetPic.Filter = "Image File (*.Gif;*.jpg)|*.Gif;*.jpg";
ofdTargetPic.Title = "Add target picture";
ofdTargetPic.Multiselect = true;
ofdTargetPic.FileName = string.Empty;
DialogResult result = ofdTargetPic.ShowDialog();
if (result == DialogResult.OK)
{
picTargetchoose.SizeMode = PictureBoxSizeMode.StretchImage;
foreach (var picture in ofdTargetPic.FileNames)
{
imgltargetpic.Images.Add(Image.FromFile(picture));//error is here
}
}
}
如果可能的話,請告訴我我可以用什么格式將 imagelist 資料保存在我的資料庫中我知道代碼我只想知道我應該在我的資料庫中打開什么空間來保存資料(imagelist 輸出資料的格式)
這是那些需要學習如何將資料添加到資料庫中的代碼
OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Target.accdb");//this addres here is based on where you save your data base
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "insert into tablename(tablefieldname,tablefieldname,...)values('" textboxName.Text "','" textboxfamily.Text "')";
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
更新的:首先是錯誤;;System.Drawing.dll 中出現“System.OutOfMemoryException”型別的未處理例外附加資訊:記憶體不足。我的問題是因為我選擇的影像已損壞!為清楚起見,我想在圖片框中顯示我的 c# windows 表單應用程式中資料庫中保存的影像資料,我選擇影像串列的原因是因為我想選擇多個影像,然后使用計時器在幻燈片中顯示它們圖片框我已經撰寫了代碼以在將其保存到資料庫之前將其顯示給用戶,這里是代碼:
int selectedpic = 0;
private void timerpicslide_Tick(object sender, EventArgs e)
{
picTargetchoose.Image = imgltargetpic.Images[selectedpic];
if (selectedpic == imgltargetpic.Images.Count -1)
{
selectedpic = 0;
}
else
{
selectedpic ;
}
}
每次計時器滴答時,我都使用計時器在影像串列中一張一張地選擇圖片(請記住在添加圖片時啟動計時器)現在的問題是我無法將保存的資料從資料庫呼叫到我的影像串列中,并且使用圖片框向用戶展示這是我正在使用的代碼:
private void cmbTarget_SelectedIndexChanged(object sender, EventArgs e)
{
con.Open();
OleDbDataAdapter da = new OleDbDataAdapter("select * from targetInfo where targetName like '" cmbTarget.SelectedItem.ToString() "%'", con);
DataTable dt = new DataTable();
da.Fill(dt);
dgvtargetview.DataSource = dt;
imglpicshow.Images.Add(Image.FromFile(dgvtargetview.CurrentRow.Cells[3].Value.ToString())); // where the problem lies
}
影像串列采用二進制資料我已按照我們的朋友@Albert D. Kallal 在答案中建議的方式將資料以 OLE 物件格式保存在我的資料庫中,但現在我無法從資料庫中取出并將其放入影像串列中以執行程序 。
謝謝你的時間!
uj5u.com熱心網友回復:
好吧,有人會假設您是否要將原始二進制檔案保存在 Access 中?然后影像控制元件可能可以找出格式,但這表明您還應該至少有另一列保存帶有擴展名的檔案名。
而且我至少會花一杯咖啡時間來真正確定您要將檔案存盤在資料庫中而不是檔案夾中,然后只將路徑名保存到資料庫表中的檔案夾中。
上面的原因很多,但這意味著:
如果你曾經想采用sql server,那么資料遷移變得非常容易。
對于任何基于 Web 的軟體 - 再次擁有一個包含影像的檔案夾的路徑是非常少的麻煩和作業。
用戶可以非常輕松地從該檔案夾“復制檔案”,在該檔案夾中搜索檔案名,并使用 啟動他們最喜歡的圖片編輯器和查看軟體。如果您將該檔案藏在資料庫中,那么您將完全無法使用任何和所有圖片編輯器,甚至圖片組織和圖片幻燈片放映軟體等。并且任何其他軟體都難以使用此類圖片。
此外,不清楚您是希望在 c# 應用程式中顯示圖片,還是希望圖片以訪問表單的形式顯示?所以這個問題在這里應該說清楚。
如前所述,您希望使用擴展名保存檔案名,因為如果您需要從資料庫中提取圖片,那么您需要檔案擴展名(除非您只允許保存一種圖片型別)。
您可以使用 Access db 中的 oleDB 型別列,或使用備忘錄。(但是,如果您將二進制保存到備忘錄型別列中,那么您需要在插入影像控制元件之前將字串轉換為 byte[]。
所以,我使用了 oleDB 型別,我的資料庫是這樣的:
請記住,我們根本沒有使用 Access 使用的 oleDB 格式。這個選擇真的很簡單,就是一個二進制資料 blob。
可以顯示在 VBA/MS-Access 中沒有一點代碼的影像,但我假設我們在 c# winform 中顯示和使用。
好的,所以說這樣的表格 - 非常簡單:
因此,在頂部,我們瀏覽到一個檔案 - 選擇它
這段代碼:
private void cmdBrowseFile_Click(object sender, EventArgs e)
{
OpenFileDialog MyFile = new OpenFileDialog();
MyFile.ShowDialog();
if (MyFile.FileNames.Length > 0)
{
txtFile.Text = MyFile.FileName;
txtFileName.Text = Path.GetFileName(txtFile.Text);
ShowPicFile(MyFile.FileName);
}
}
void ShowPicFile(string sFile)
{
pictureBox1.Image = ByteToImage(File.ReadAllBytes(sFile));
}
public static Bitmap ByteToImage(byte[] blob)
{
Bitmap image;
using (MemoryStream stream = new MemoryStream(blob))
image = new Bitmap(stream);
return image;
}
因此,如果我們瀏覽到檔案 - 我們會顯示(未保存到資料庫)。
像這樣說:
所以,我只取檔案名,塞入右下角的框,然后點擊保存到資料庫
它將添加/保存到資料庫。該代碼是這樣的:
private void cmdSave_Click(object sender, EventArgs e)
{
// save picture as bytes to DB
byte[] fData = File.ReadAllBytes(txtFile.Text);
string strSQL =
@"INSERT INTO MyPictures (FileName, PictureData)
VALUES(@File, @Data)";
OleDbCommand cmdSQL = new OleDbCommand(strSQL);
cmdSQL.Parameters.Add("@File", OleDbType.VarWChar).Value = txtFileName.Text;
cmdSQL.Parameters.Add("@Data", OleDbType.Binary).Value = fData;
MyRstP(cmdSQL, false);
// display in grid
cmdSQL.CommandText = "SELECT ID, FileName FROM MyPIctures";
cmdSQL.Parameters.Clear();
dataGridView1.DataSource = MyRstP(cmdSQL);
MessageBox.Show("saved");
}
現在新行出現在我們的網格中。我可以單擊任何行,然后單擊 DB 中的顯示。該代碼是這樣的:
private void cmdShow_Click(object sender, EventArgs e)
{
int pk = (int)dataGridView1.CurrentRow.Cells[0].Value;
OleDbCommand cmdSQL =
new OleDbCommand("SELECT ID, PictureData FROM MyPictures WHERE ID = @ID");
cmdSQL.Parameters.Add("@ID", OleDbType.Integer).Value = pk;
DataRow OneRow = MyRstP(cmdSQL).Rows[0];
pictureBox1.Image = ByteToImage((byte[])OneRow["PictureData"]);
}
還有我的助手程式
DataTable MyRstP(OleDbCommand cmdSQL, bool ReturnsData = true)
{
DataTable rstData = new DataTable();
using (OleDbConnection conn = new OleDbConnection(Properties.Settings.Default.AccessDB))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
if (ReturnsData)
rstData.Load(cmdSQL.ExecuteReader());
else
cmdSQL.ExecuteNonQuery();
}
}
return rstData;
}
和
public static Bitmap ByteToImage(byte[] blob)
{
Bitmap image;
using (MemoryStream stream = new MemoryStream(blob))
image = new Bitmap(stream);
return image;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/505133.html
上一篇:在SELECT查詢中設定列中的值