2010-01-26 34 views
6

Tôi có cơ sở dữ liệu đơn giản trong tệp .mdb Access, nhưng tôi không biết cách xử lý: "tham số không hợp lệ" ngoại lệ khi Im tạo Image từ luồng. Tôi đã đọc rằng tôi cần phải bỏ qua 78 byte bù trừ (from here) nhưng tôi vẫn còn nhận lỗi "thông số không hợp lệ" khi tôi gọi TừStream, ngay cả sau khi tước bỏ 78 byte đầu tiên.Đọc hình ảnh từ Access - tham số không hợp lệ


này không làm việc cho tôi:

byte[] abytPic = (byte[])dt.Rows[0]["Photo"]; byte arrary with image 
if ((abytPic[0] == 21) && (abytPic[1] == 28)) //It's true 
{ 
    byte[] abytStripped = new byte[abytPic.Length - 78]; 
    System.Buffer.BlockCopy(abytPic, 78, abytStripped, 0, abytPic.Length - 78); 
    msPic = new emoryStream(abytStripped); 
} 
+0

Khi bạn xem bảng MS Access có chứa cột Hình ảnh, bạn thấy gì trong trường? Có phải 'Dữ liệu nhị phân dài' hay thứ gì đó khác? – Stewbob

Trả lời

6

Nếu bạn đang đọc dữ liệu trực tiếp từ MS Access, bạn không cần phải tước bất kỳ thông tin tiêu đề.

Giả sử các hình ảnh được lưu giữ như một BLOB, mà là phổ biến nhất, đây là mã để đọc trong mảng byte từ cơ sở dữ liệu và lưu trữ như một file ảnh (xin lỗi, VB thay vì C#):

Dim varBytes() As Byte 

    Using cn As New OleDbConnection(myConnectionString) 
    cn.Open() 

    sqlText = "SELECT [myColumn] " _ 
       & "FROM [myTable] " _ 
       & "WHERE ([mySearchCriteria] = '" & mySearchTerm & "')" 

    Using cm As New OleDbCommand(sqlText, cn) 
     Dim rdr As OleDbDataReader 

     rdr = cm.ExecuteReader 

     rdr.Read() 

     varBytes = rdr.GetValue(0) 
    End Using 

    End Using 

    My.Computer.FileSystem.WriteAllBytes(myPath & "\myFile.emf", varBytes, True) 

Ví dụ này mà tôi đã đặt xung quanh là một trong những nơi tôi biết các tệp trong cơ sở dữ liệu là hình ảnh .emf. Nếu bạn biết phần mở rộng, bạn có thể đặt nó vào tên tập tin. Nếu không, bạn có thể để trống và sau đó mở kết quả bằng trình xem hình ảnh; nó sẽ bắt đầu. Nếu bạn cần tìm phần mở rộng hoặc loại tệp, khi nó được lưu dưới dạng tệp, bạn có thể mở tệp đó bằng bất kỳ trình chỉnh sửa hex nào và loại tệp sẽ có sẵn từ thông tin tiêu đề.

Câu hỏi của bạn có một chút không rõ ràng, vì vậy tôi không chắc mã trên là chính xác những gì bạn muốn, nhưng nó sẽ giúp bạn gần gũi hơn rất nhiều.

EDIT:

Đây là mã VB mà sẽ đưa mảng byte, tải nó vào một đối tượng MemoryStream, và sau đó tạo ra một đối tượng hình ảnh từ Stream. Đoạn mã này hoạt động tốt và hiển thị hình ảnh trong một hình tượng trên biểu mẫu của tôi.

Dim img As Image 
    Dim str As New MemoryStream(varBytes) 
    img = Image.FromStream(str) 
    PictureBox1.Image = img 

Nếu C# tương đương với điều này không hoạt động cho bạn thì vấn đề có thể là cách lưu trữ hình ảnh trong cơ sở dữ liệu MS Access.

EDIT:

Nếu hình ảnh trong cơ sở dữ liệu của bạn được lưu giữ như một 'gói' và không phải là một 'dữ liệu nhị phân dài', sau đó bạn sẽ cần phải dải thông tin tiêu đề mà MS Access thêm. Tôi đã chơi với loại 'Gói' lưu trữ hình ảnh với một tệp .jpg đơn giản. Tiêu đề trong trường hợp này dài hơn 78 byte. Trong trường hợp này, nó thực sự là 234 byte, và MS Access cũng thêm một số thông tin vào cuối tập tin gốc; khoảng 292 byte trong trường hợp này.

Có vẻ như cách tiếp cận ban đầu của bạn là chính xác, bạn sẽ chỉ cần xác định số byte để loại bỏ phần trước và sau mảng Byte cho trường hợp của bạn.

Tôi đã xác định nó cho tệp của mình bằng cách so sánh tệp hình ảnh gốc và tệp được xuất từ ​​cơ sở dữ liệu, (không phải đối tượng Luồng, xem mã đầu tiên của tôi) trong trình chỉnh sửa hex. Một khi tôi đã tìm ra bao nhiêu thông tin (header và footer) đã được MS Access thêm vào, sau đó tôi biết có bao nhiêu byte cần được loại bỏ.

EDIT:

Kích thước của tiêu đề bổ sung bởi MS Access khi hình ảnh được lưu trữ như là 'gói' khác nhau tùy thuộc vào loại tập tin, và vị trí ban đầu (đầy đủ thông tin đường dẫn) của hình ảnh khi nó đã được đưa vào cơ sở dữ liệu MS Access. Vì vậy, ngay cả đối với cùng một loại tệp, bạn có thể có một số lượng byte khác nhau để tách khỏi tiêu đề cho mỗi tệp. Điều này làm cho nó khó khăn hơn nhiều, bởi vì sau đó bạn sẽ phải quét mảng byte cho đến khi bạn tìm thấy thông tin bắt đầu thông thường của tệp đó và sau đó loại bỏ mọi thứ trước nó.

Tất cả nhức đầu này là một trong những lý do tốt hơn để lưu trữ hình ảnh dưới dạng dữ liệu nhị phân dài BLOB 'trong cơ sở dữ liệu. Retrieval dễ dàng hơn nhiều. Tôi không biết nếu bạn có tùy chọn để làm điều này, nhưng nếu như vậy, nó sẽ là một ý tưởng tốt.

+0

Nhưng khi Im cố gắng để nhanh chóng đối tượng của loại hình ảnh, đi qua mảng byte (varBytes trong ví dụ của bạn) như tham số constructor, Im nhận được lỗi: Tham số không hợp lệ. Ofcourse đây là một mảng byte hợp lệ (có chiều dài khoảng 3000 byte - tùy thuộc vào kích thước hình ảnh). – Dariusz

+0

Cảm ơn có vẻ như không có giải pháp nào để có được chiều dài của tiêu đề OleObject. Cảm ơn sự hỗ trợ của bạn. – Dariusz

1

Tôi không tin rằng vấn đề của bạn là với cơ sở dữ liệu. Các ngoại lệ "Tham số không hợp lệ" khi xử lý hình ảnh có thể là một nỗi đau tổng thể như tôi đã xử lý với chúng trước đây. Họ không rõ ràng về vấn đề là gì.

Hình ảnh được đặt vào cơ sở dữ liệu chính xác như thế nào? Có thể có vấn đề khi viết hình ảnh vào cơ sở dữ liệu trước khi bạn cố gắng kéo nó. Ngoài ra, loại tệp nào là hình ảnh?

EDIT Đây là một số mã mẫu mà tôi đã sử dụng trước đây để lấy hình ảnh từ một mảng byte.

 //takes an array of bytes and converts them to an image. 
    private Image getImageFromBytes(byte[] myByteArray) 
    {    
     System.IO.MemoryStream newImageStream = new System.IO.MemoryStream(myByteArray, 0, myByteArray.Length); 
     return Image.FromStream(newImageStream, true); 
    } 
+0

LƯU Ý: Tất cả điều này giả định rằng bạn đang lấy lại các giá trị hợp lệ từ cuộc gọi cơ sở dữ liệu của mình. – Aaron

Các vấn đề liên quan