I added many JPEG images into an Access DB as Long binary data. Now I want to retrieve these images into a TImage
using Delphi code.
For this work, I wrote the code below, but after running it gives me a JPEG error #53 error. I searched in Google for this error code, and tried some solutions, such as saving as picture to new JPG format, but that does not change anything.
Also, I found different codes for retrieving an image from a database, but all of them gave me the same JPEG error #53 error.
Where is the problem?
procedure RetrieveImage;
var
Jpg : TGraphic;
Stream: TStream;
query : string;
Field: TBlobField;
Begin
Stream := nil;
Jpg := nil;
query := 'Select JPGFile From Table Where Name=' + QuotedStr(SoftName);
Try
With ADOQuery do
Begin
Try
SQL.Clear;
SQL.Add(query);
Open;
Field := TBlobField(FieldbyName('JPGFile'));
Stream := CreateBlobStream(Field,bmRead);
Jpg := TJpegImage.Create;
Jpg.LoadFromStream(Stream);
MainForm.PictureBox.Picture.Graphic:= Jpg;
Finally
Close;
End;
End;
Finally
Stream.Free;
Jpg.Free;
End;
End;
EDIT:
I used C# code for insert a JPG file into the database (the following code is simplified):
// Insert Data to Access tables
private void InsertToTable(string connectionString, string query)
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
try
{
connection.Close();
using (OleDbCommand command = new OleDbCommand(query, connection))
{
connection.Open();
using (OleDbDataReader reader = command.ExecuteReader())
{
reader.Close();
}
command.Cancel();
}
connection.Close();
}
finally
{
connection.Close();
}
}
}
// Insert Image into database
private void SaveToDataBase(string jpegPath)
{
//jpegPath example is: (C:\Image\1.jpg)
string FilePath = Application.StartupPath + directory + dbName;
string MDBConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + FilePath + "; Jet OLEDB:Engine Type=5";
// Convert Image to binary
var image = File.ReadAllBytes(jpegPath);
InsertToTable(MDBConnStr, $"INSERT INTO Table JPGFile VALUES('{image}')");
}
In your C# code, why are you using
ExecuteReader()
to execute anINSERT
statement? You should be usingExecuteNonQuery()
instead.More importantly, you are not actually inserting the contents of your
image
byte array into the database, which is why Delphi'sTJPEGImage
is failing to load the data later. Your SQL query is being created as an interpolated string, but your{image}
expression does not insert the raw bytes into the query, like you think it does. And even if it did, that is not the correct way to insert raw bytes into a "Long Binary" field to begin with.You need to use a parameterized query instead. Add an
OleDbParameter
to thecommand.Parameters
collection to pass theimage
data into the database, where you set itsDbType
property toBinary
, itsOleDbType
property to eitherBinary
,LongVarBinary
, orVarBinary
, and itsValue
property to yourimage
byte array. You can then refer to that parameter in your SQL statement.See Configuring parameters and parameter data types, especially the section on Using parameters with an OleDbCommand or OdbcCommand.
Try something more like this:
Note, however, that binary parameters in OLEDB are limited to 8000 bytes max.