PDA

View Full Version : Trong C#: đưa file ảnh vào CSDL?



hoctap222
16-02-2009, 14:04
Tôi dùng CSDL SQL2000, các bạn cho mình hỏi nếu dùng trường lưu file ảnh .jpg thì dùng trường đó bằng kiểu gì? Xin cảm ơn!

serivn
16-02-2009, 21:15
CSDL không thể lưu trực tiếp được các đối tượng thực thể như là Aduio, Image,... Nếu bạn muốn dùng CSDL để lưu trữ ảnh thì bạn chỉ có thể dùng để lưu trữ đường dẫn tới file ảnh hay bất cứ file nào khác mà bạn muốn. Ví dụ nếu bạn muốn tạo một có sở dữ liệu lưu một trang ảnh chẳng hạn, bạn có thể thành lập một CSDL có một Table với các trường như: ImageID, URL, height, width,.. Để miêu tả đối tượng đó.
Chúc bạn thành công!!!:)

vmhuong
17-02-2009, 14:27
CSDL không thể lưu trực tiếp được các đối tượng thực thể như là Aduio, Image,... Nếu bạn muốn dùng CSDL để lưu trữ ảnh thì bạn chỉ có thể dùng để lưu trữ đường dẫn tới file ảnh hay bất cứ file nào khác mà bạn muốn. Ví dụ nếu bạn muốn tạo một có sở dữ liệu lưu một trang ảnh chẳng hạn, bạn có thể thành lập một CSDL có một Table với các trường như: ImageID, URL, height, width,.. Để miêu tả đối tượng đó.
Chúc bạn thành công!!!:)

Luyên thuyên
Ảnh có thể đưa thẳng vào cơ sở dữ liệu, có thể dùng kiểu image hoặc kiểu nhị phân. vấn đề là khi lấy ra

serivn
17-02-2009, 18:06
Luyên thuyên
Ảnh có thể đưa thẳng vào cơ sở dữ liệu, có thể dùng kiểu image hoặc kiểu nhị phân. vấn đề là khi lấy ra

Hì!!!
Cái này cũng có thể, mình chưa có dùng kiểu đó bao giờ nên đã nói sai rùi. Tiện thể bạn có thể đưa ra giải pháp cho câu hỏi của bạn ấy luôn đi!! Mình cũng muốn được học hỏi thêm.
Rất mong được bạn giúp đỡ nhiều!!!:)

hitman2584
17-02-2009, 21:47
Hì!!!
Cái này cũng có thể, mình chưa có dùng kiểu đó bao giờ nên đã nói sai rùi. Tiện thể bạn có thể đưa ra giải pháp cho câu hỏi của bạn ấy luôn đi!! Mình cũng muốn được học hỏi thêm.
Rất mong được bạn giúp đỡ nhiều!!!:)
SQLserver lưu dưới dạng binary, C# dùng hàm xử lý ảnh (image) đọc ra chuỗi nhị phân -> insert vào database. Lâu rồi ko làm nên ko nhớ lắm, nhưng đã từng làm rồi. Nhưng dùng cách này ko phổ biến lắm.

serivn
18-02-2009, 05:04
Cảm ơn các bạn nhiều!!
Mình đã tìm rồi, có khá nhiều thuật toán hay về cái này. Bởi trước đây mình ko nghĩ là có cái nè nên cũng lười tìm hiểu luôn, ai dè mình sai quá.
Một lần nữa cảm ơn rất nhiều, mình lại có một bài học bổ ích!!1:)

hoctap222
19-02-2009, 14:32
Bạn nói đúng, mình cũng có hỏi sơ qua thì lưu trong CSDL là một kiểu nhị phân. Chuyển từ fie ảnh đó vào nhị phân sau đó trích lại. Nhưng vấn đề là cụ thể nó như thế nào thì cũng chưa rõ đươc. Mong các bạn có kinh nghiệm truyền đạt. Xin cảm ơn các bạn đã quan tâm.

sinhviencongnghe
20-02-2009, 14:45
cnn = new SqlConnection(connString);
cnn.Open();
string strSQL = "Insert Into Products(ProductName,Image,ImgLength,ImgType) values (@ProductName,@Image,@ImgLength,@ImgType)";
cmd = new SqlCommand(strSQL, cnn);

param = new SqlParameter("@ProductName", SqlDbType.VarChar);
param.Value = txtProductName.Text;
cmd.Parameters.Add(param);

param = new SqlParameter("@Image", SqlDbType.Image);
param.Value = content;
cmd.Parameters.Add(param);

param = new SqlParameter("@ImgLength", SqlDbType.BigInt);
param.Value = length;
cmd.Parameters.Add(param);

param = new SqlParameter("@ImgType", SqlDbType.VarChar);
param.Value = type;
cmd.Parameters.Add(param);

cmd.ExecuteNonQuery();
cnn.Close();

shinobiBT
21-02-2009, 02:40
uhm, khi bạn muốn lưu ảnh vào trong CSDL thì đừng nên lưu file trực tiếp mà bạn hãy lưu đườn dẫn file lên ấy. Trong vd của bạn sinhviencongnghe mình sửa lại là

.....
param = new SqlParameter("@Image", SqlDbType.Varchar);
param.value = UploadToServer(txtFilename.text);
cmd.parameters.add(param);

Hàm UploadToServer bạn có thể viết code để upload file lên sever và trả lại string là server.mappath đến file mà bạn vừa up lên

sinhviencongnghe
21-02-2009, 11:04
Hi`hi`
Người ta hỏi mình lưu ảnh vào CSDL mà, đâu hỏi giái pháp nào hợp lý hơn đâu.
Mình chỉ trả lời đúng những gì người ấy hỏi do nhu cầu mỗi người khác nhau :)

hoctap222
26-02-2009, 15:11
Cho mình hỏi nếu như lưu vào CSDL bằng đường dẫn thì mình phải lưu thêm một thư mục nữa phải không? Nếu như thế thì bất tiện nếu như thư mục đó có hàng nghìn ảnh và ngày càng nhiều. Còn nếu lưu trực tiếp ảnh vào CSDL có vẽ tiện hơn.

shinobiBT
27-02-2009, 02:39
uhm, đúng là có 2 giải pháp 1. Lưu ảnh trên CSDL và 2. Lưu ảnh trên đĩa cứng.

1. Lưu ảnh trên CSDL
Ưu: Dễ Backup, không cần điều chỉnh Disk Permission cho tài khoản ASP.NET
Khuyết: CSDL hiện nay khá mắc, nếu mà lưu trăm nghìn ảnh khác cũng phải tốn vài triệu 1 tháng, hơn nữa còn làm ảnh hưởng đến tốc độ của CSDL

2. Lưu ảnh trên ỗ cứng
Ưu: Dung lượng nhiều, tiện lợi khi download
Không cần phải viết code handle các file ảnh lớn hơn 4MB
Khuyết: Phải điều chỉnh Disk Permission, Bandwith chắc bị sứt mẻ mấy trăm MB

Tùy theo hoàn cảnh bạn chọn cách nào phù hợp thôi, đó là tùy ở bạn

hoctap222
27-02-2009, 16:08
Nếu lưu thư mục ảnh riêng ngoài CSDL thì việc truy cập CSDL nhẹ hơn. Và mình lưu đường dẫn vào CSDL nhưng việc hiển thị ảnh ra như thế nào ?

serivn
27-02-2009, 23:37
+ Nếu mà dùng control PictureBox thì gán url của nó (Image.FromFile(url))bằng cái đường dẫn load ra từ CSDL
+ Còn nếu dùng HTML để hiển thị thì: <img height="" width="" src=".......">
........

hoctap222
23-04-2009, 10:24
Tại sao khi mình gán String Url="D:\Hinhanh\anh.bmp" thì nó báo lỗi. Nó có phân biệt "\" cho nên nó báo dòng đỏ sau dấu "\". các bạn cho ýe kiến..

[=========> Bổ sung bài viết <=========]

Mình tìm ra được rồi: Url=@"D:\Hinhanh\anh.bmp". phải có dấu @ phía trước. Nếu có ai dùng đến nó thì chính nó.

duongdragonxxx
24-04-2009, 09:50
//áp dụng kiểu lấy data này cho bất kỳ kiểu file nào cũng dc
//Lấy data dạng binary
Stream imgStream = UploadFile.PostedFile.InputStream;
int imgLen = UploadFile.PostedFile.ContentLength;
string imgContentType = UploadFile.PostedFile.ContentType;
string imgName = txtImgName.Value;
byte[] imgBinaryData = new byte[imgLen];
int n = imgStream.Read(imgBinaryData,0,imgLen);

- đối với trường hợp trong winform thì cần save binary read dc từ db lên thành file tạm rồi mới hiển thị dc.
- Riêng đối với asp.net thì bạn có thể write trực tiếp vào Response stream. Do vậy ở đây chúng ta nên code riêng thành 1 cái handler kiểm soát việc write file xuống cho client

[=========> Bổ sung bài viết <=========]

đối với mô hình lưu trữ hiện nay hệ thống db cũng khá mạng. Các chuơng trình các bạn code thực tế lượng tin cũng chỉ mức nhỏ. Do đó có thể chứa hẳn file trong db luôn. Mỗi lần di chuyển cho tiện.

@shinobiBT: việc tốn bandwidth thì đưa file kiểu nào ra cũng đều dc tính cả, 2 trường hợp đều tốn như nhau

ITVnese
28-04-2009, 13:56
Lưu image trong DB chỉ dành cho một số trường hợp đặc biệt thôi bạn à.

Bandwidth đi về với DB của những hệ thống lớn rất quan trọng nên không thể gọi là tốn như nhau được.
Một server database chỉ quản lý một số transaction nhất định và có sử dụng cơ chế pooling để quản lý không để overload database server. Nếu đơn giản bạn chỉ cần load một hình ảnh thì cứ như load một file text lên thôi.
Những thứ không quan trọng và không cần tính bảo mật thì không nên để trong database.

duongdragonxxx
29-04-2009, 08:58
@ITVnese:

Lưu image trong DB chỉ dành cho một số trường hợp đặc biệt thôi bạn à.
Như thế sharepoint của M$ chắc cũng hàng đặc biệt.


Lưu image trong DB chỉ dành cho một số trường hợp đặc biệt thôi bạn à. Nói như thế là data để trong db tính bảo mật cao hơn. Về điểm này tui không dồng tình à.

thichhochoi1
29-04-2009, 16:21
Url="D:\\Hinhanh\\anh.bmp"

WhiteKnight
30-04-2009, 02:57
Cho mình hỏi nếu như lưu vào CSDL bằng đường dẫn thì mình phải lưu thêm một thư mục nữa phải không? Nếu như thế thì bất tiện nếu như thư mục đó có hàng nghìn ảnh và ngày càng nhiều. Còn nếu lưu trực tiếp ảnh vào CSDL có vẽ tiện hơn.

Nói như bạn thì hàng ngàn file hình ảnh lưu vào thư mục ngày càng nhiều. Vậy nếu bạn lưu vào CSDL thì trở thành 1 cục database rất nặng nề, mỗi lần truy xuất thì SQL phải duyệt qua cả núi dữ liệu -> lâu, còn lưu vào thư mục thì data chỉ chứa đường dẫn (dạng text) nên rất nhẹ, mỗi lần chỉ truy xuất file ảnh cần dùng nên nhanh hơn, vậy bạn thấy cách nào tối ưu hơn?:blink:

serivn
01-05-2009, 00:38
Tại sao khi mình gán String Url="D:\Hinhanh\anh.bmp" thì nó báo lỗi. Nó có phân biệt "\" cho nên nó báo dòng đỏ sau dấu "\". các bạn cho ýe kiến..

[=========> Bổ sung bài viết <=========]

Mình tìm ra được rồi: Url=@"D:\Hinhanh\anh.bmp". phải có dấu @ phía trước. Nếu có ai dùng đến nó thì chính nó.

Trong C/C++/C# thì dấu "\" là dấu dùng để hiện thỉ các kí tự được dùng như để nhận dạng trong lập trình như : ", ', \, vì thế khi viết đường dẫn không thể viết như thông thường. Trong C# có 2 cách để giải quyết, một là dùng thêm một dấu "\" nữa, VD: đường dẫn "D:\tmp\abc.txt" thì phải viết thành "D:\\tmp\\abc.txt", hoặc thêm kí tự "@" vào trước để xác định đó là một chuỗi thuần (Cách này dễ hơn:) ).

hoaianhmonster
02-05-2009, 11:35
Lưu ảnh vào CSDL SqlServer2000
Tạo một trường BinaryImage ; Type : Image

Kiểm tra file được upload là một file ảnh :

byte[] image=null;
bool FileOK = false;
int[] value = new int[2] {0,0};
String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
if (ImgUploader.HasFile)
{
string extension = Path.GetExtension(ImgUploader.FileName).ToLower();
for (int i = 0; i < allowedExtensions.Length; i++)
{
if (extension == allowedExtensions[i])
{
FileOK = true;
}
}
}

Upload lên CSDL :
if (FileOK == true)
{
Sql.Parameter.Add("@Image",SqlDbtype.Image).value=image
}

Vậy khi cần hiển thị ảnh ta sử dụng một file ashx và COntrol Image :
<asp:Image runat="server" url="ImageReader.ashx?idimage="+idImage>
</asp:Image>

duongdragonxxx
04-05-2009, 16:18
Nói như bạn thì hàng ngàn file hình ảnh lưu vào thư mục ngày càng nhiều. Vậy nếu bạn lưu vào CSDL thì trở thành 1 cục database rất nặng nề, mỗi lần truy xuất thì SQL phải duyệt qua cả núi dữ liệu -> lâu, còn lưu vào thư mục thì data chỉ chứa đường dẫn (dạng text) nên rất nhẹ, mỗi lần chỉ truy xuất file ảnh cần dùng nên nhanh hơn, vậy bạn thấy cách nào tối ưu hơn?:blink:

Đồng ý lưu vào db thì db trở nên nặng nề hơn. Nhưng về việc duyệt dữ liệu có khả năng truy xuất nhiều như nhau. Một bên là HĐH truy xuất file, và 1 bên do mình select file trong db. Hơn nữa lúc này việc di chuyển cũng khá nhẹ nhàng, chỉ xách mỗi cái db đi chỗ # là dc.

up2store
04-05-2009, 18:25
Như thế sharepoint của M$ chắc cũng hàng đặc biệt.

Nói như thế là data để trong db tính bảo mật cao hơn. Về điểm này tui không dồng tình à.

Sharepoint của Microsoft, nó lưu là vì nó phát triển trên những sản phẩm của Microsoft nên nó có cách tổ chức, xử lý sao cho dữ liệu truy xuất nhanh, gà mờ không nên lưu nếu nguồn dữ liệu nhiều, vì làm rứa database sẽ rất nặng và truy xuất chậm:emlaugh:

serivn
06-05-2009, 02:26
Nói như bạn thì hàng ngàn file hình ảnh lưu vào thư mục ngày càng nhiều. Vậy nếu bạn lưu vào CSDL thì trở thành 1 cục database rất nặng nề, mỗi lần truy xuất thì SQL phải duyệt qua cả núi dữ liệu -> lâu, còn lưu vào thư mục thì data chỉ chứa đường dẫn (dạng text) nên rất nhẹ, mỗi lần chỉ truy xuất file ảnh cần dùng nên nhanh hơn, vậy bạn thấy cách nào tối ưu hơn?:blink:

Bạn nói như vậy là không chính xác. Trong khi mình lấy ảnh từ CSDL, SQL Server không hề "phải trải qua núi dữ liệu" bởi vì nó cũng sẽ lấy lấy cái ảnh đó như lấy môt record thông thường, và tìm kiếm nó bằng Index chứ không phải dò trên khối dữ liệu theo dạng "cục" như bạn nói, việc lưu ảnh ở đây nếu có chăng là gây khó khăn cho Backup mà thôi!!

duongdragonxxx
07-05-2009, 02:00
nó lưu là vì nó phát triển trên những sản phẩm của Microsoft nên nó có cách tổ chức, xử lý sao cho dữ liệu truy xuất nhanh
hic đang dùng sql server box .net