12/31/13

[SQL Server, Access] Lưu hình ảnh vào database

Trong bài viết này tôi sẽ hướng dẫn bạn cách chèn hình ảnh trực tiếp vào database. Cách này tuy làm cho database lớn/nặng nhưng nó cũng giải quyết rất nhiều vấn đề trong quá trình lập trình.
Ở đây, csdl tôi sử dụng là ms Access và MS SQLserver.
Cách 1: Database là Access

1. Bạn tạo 1 file access có tên TestDB.mdb nằm trong thư mục bin\debug của ứng dụng(chỗ khác cũng không sao, tùy).Tạo 1 bảng có tên tblSinhvien có cấu trúc như sau:
Tên fieldKiểu dữ liệu
MSSVText(15)
hinhAnhOLE Object
2. Tạo 1 Windows Form Application  Project có tên Store_Retrieve_Image_From_DB.
3. Tạo lớp có tên ConnectDB.cs với nội dung sau:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;namespace Store_Retrieve_Image_From_DB
{
public class ConnectDB
{
private OleDbConnection con;
private DataSet ds;
private OleDbDataAdapter daSV;
/// <summary>
/// Phương thức constructor khởi tạo kết nối đến database
/// </summary>
public ConnectDB()
{
try
{
con = new OleDbConnection();
con.ConnectionString = “Provider=microsoft.jet.OLEDB.4.0;Data Source=”+
System.Windows.Forms.Application.StartupPath+”\\TestDB.mdb”;
con.Open();
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Lấp về tất cả các mẫu tin trong bảng tblSinhvien
/// </summary>
/// <returns></returns>
public DataSet GetTable()
{
ds = new DataSet();
daSV = new OleDbDataAdapter(“select * from tblSinhvien”, con);
daSV.Fill(ds, “tblSinhvien”);
return ds;
}
/// <summary>
/// Cập nhật các thay đổi của người dùng
/// </summary>
public void UpdateSV()
{
try
{
OleDbCommandBuilder bd = new OleDbCommandBuilder(daSV);
daSV.Update(ds, “tblSinhvien”);
}
catch (Exception)
{
throw;
}
}
}
}
Lớp này dùng để đọc dữ liệu từ database cũng như cập nhật dữ liệu xuống database.
3. Thiết kế MainForm như hình
dbimage_cs_01.png
4. Code cho Form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;namespace Store_Retrieve_Image_From_DB
{
public partial class MainForm : Form
{
private ConnectDB conDB;
private DataSet ds = new DataSet();
private BindingSource bs;
private DataTable dtSV;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
try
{
conDB = new ConnectDB();
ds = conDB.GetTable();
dtSV = ds.Tables["tblSinhvien"];
bs = new BindingSource(ds, “tblSinhvien”);
bs.CurrentItemChanged += new EventHandler(bs_CurrentItemChanged);
dataGridView1.DataSource = bs;
bindingNavigator1.BindingSource = bs;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
/// <summary>
/// Sự kiện xảy ra khi binding source có sự thay đổi do người
/// dùng chọn các dòng trên lưới hặc nhấn các nút di chuyển.
/// </summary>
/// <param name=”sender”></param>
/// <param name=”e”></param>
void bs_CurrentItemChanged(object sender, EventArgs e)
{
DataRowView row = (DataRowView)bs.Current;
try
{
Byte[] i = (byte[])row["hinhAnh"];
MemoryStream stmBLOBData = new MemoryStream(i);
picHinhAnh.Image = Image.FromStream(stmBLOBData);
}
catch (Exception ex)
{
picHinhAnh.Image = null;
MessageBox.Show(ex.ToString());
}
}
private void btnLuu_Click(object sender, EventArgs e)
{
try
{
DataRow dr = dtSV.NewRow();
dr["MSSV"] = txtMSSV.Text;
if (picHinhAnh.Image != null)
{
MemoryStream ms = new MemoryStream();
picHinhAnh.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Byte[] bytBLOBData = new Byte[ms.Length];
ms.Position = 0;
ms.Read(bytBLOBData, 0, Convert.ToInt32(ms.Length));
dr["hinhAnh"] = bytBLOBData;
dtSV.Rows.Add(dr);
conDB.UpdateSV();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void btnLoadHinh_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = “JPG Files(*.JPG)|*.JPG|GIF Files(*.GIF)|*.GIF”;
if (dlg.ShowDialog(this) == DialogResult.OK)
{
picHinhAnh.Image = Image.FromFile(dlg.FileName);
}
}
}
}
Chú ý:
Để đọc dữ liệu hình ảnh ra ta dùng 1 mảng Byte để chứa giá trị của field hình ảnh. Sau đó muốn hiển thị nó lên PictureBox ta phải dùng MemoryStream để đưa ra:
Byte[] i = (byte[])row["hinhAnh"];
MemoryStream stmBLOBData = new MemoryStream(i);
picHinhAnh.Image = Image.FromStream(stmBLOBData);
Để cập nhật dữ liệu vào db, ta phải lấy ảnh từ  PictureBox vào 1 MemoryStream:
MemoryStream ms = new MemoryStream();
picHinhAnh.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Rồi sau đó mới chuyển nó thành mảng Byte rồi cung cấp cho 1 datarow để update xuống database.
Byte[] bytBLOBData = new Byte[ms.Length];
ms.Position = 0;
ms.Read(bytBLOBData, 0, Convert.ToInt32(ms.Length));
dr["hinhAnh"] = bytBLOBData;
dtSV.Rows.Add(dr);
Chạy ứng dụng, kết quả như hình sau:
dbimage_cs_02.png
Cách 2: Database là Microsoft SQL Server
1. Tạo database có tên: TestImageDB với 1 bảng có tên tblImages và có cấu trúc như hình sau:
dbimage_cs_03.png
2. Tạo stored project có tên InsertImage với sql script như sau:
CREATE PROCEDURE InsertImage
@filename nvarchar(250),
@blobdata image
AS
insert into tblImages values(
@filename, @blobdata
)
3. Tạo Windows Form Application Project có tên AnotherWay.
4. Tạo lớp ConnectDB.cs có nội dung như sau:
using System;
using System.Collections.Generic;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace AnotherWay
{
class ConnectDB
{
private SqlConnection conn;
private string connectionString = “Server=.;UID=sa;PWD=;Initial Catalog=TestImageDB”;
public ConnectDB()
{
conn = new SqlConnection(connectionString);
}
public void StorePicture(string filename)
{
byte[] imageData = null;
// Read the file into a byte array
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
imageData = new Byte[fs.Length];
fs.Read(imageData, 0, (int)fs.Length);
}
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(“InsertImage”, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue(“@filename”, filename);
cmd.Parameters["@filename"].Direction = ParameterDirection.Input;
cmd.Parameters.Add(“@blobdata”, SqlDbType.Image);
cmd.Parameters["@blobdata"].Direction = ParameterDirection.Input;
// Store the byte array within the image field
cmd.Parameters["@blobdata"].Value = imageData;
conn.Open();
cmd.ExecuteNonQuery();
}
}
public byte[] RetrieveImage()
{
byte[] imageData = null;
conn.Open();
SqlCommand cmd = new SqlCommand(“select blobdata from tblImages”, conn);
// Assume previously established command and connection
// The command SELECTs the IMAGE column from the table
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
reader.Read();
// Get size of image data – pass null as the byte array parameter
long bytesize = reader.GetBytes(0, 0, null, 0, 0);
// Allocate byte array to hold image data
imageData = new byte[bytesize];
long bytesread = 0;
int curpos = 0;
int chunkSize = 1;
while (bytesread < bytesize)
{
// chunkSize is an arbitrary application defined value
bytesread += reader.GetBytes(0, curpos, imageData, curpos, chunkSize);
curpos += chunkSize;
}
}
conn.Close();
// byte array ‘imageData’ now contains BLOB from database
return imageData;
}
}
}
5. Thiết kế Form như hình
dbimage_cs_04.png
6. Code cho Form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace AnotherWay
{
public partial class Form1 : Form
{
private ConnectDB conDB;
public Form1()
{
InitializeComponent();
conDB = new ConnectDB();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = “JPG Files(*.JPG)|*.JPG|GIF Files(*.GIF)|*.GIF”;
if (dlg.ShowDialog(this) == DialogResult.OK)
{
conDB.StorePicture(dlg.FileName);
}
}
private void button2_Click(object sender, EventArgs e)
{
byte[] img = conDB.RetrieveImage();
MemoryStream str = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(str);
}
}
}
7. Thực thi
Trước hết nhấn nút Lưu, sau đó muốn xem lại mẫu tin đã lưu, nhấn nút load.
dbimage_cs_05.png

No comments: