jose rodriguez
asked on
How to show .jpg image on BLOG using DBCtrlGrid and DBImage component
I am using Delphi con connect to mysql, using myDac componentes (paid version).
I have a table called items(upc,description,reta il,picture ).
picture is a Blob Field storing .bmp or .jpg images.
How can I show a .jpg image from a BLOB field using the DBCtrlGrid and DBImage component on Delphi XE7.
There is no way for me to have .jpg in the Blob and be able to show it on the DBImage over the DBCtrlGrid, as if .bmp is the only image supported, only .bmp works ok.
I used the DBCTRLGRID to arrange the way visual components should display information, but it seems only to support display for .gmp images, I already put in use the .jpeg library but no luck.
DBCtrol_grid_noJPG_SUPPORT.png
I have a table called items(upc,description,reta
picture is a Blob Field storing .bmp or .jpg images.
How can I show a .jpg image from a BLOB field using the DBCtrlGrid and DBImage component on Delphi XE7.
There is no way for me to have .jpg in the Blob and be able to show it on the DBImage over the DBCtrlGrid, as if .bmp is the only image supported, only .bmp works ok.
I used the DBCTRLGRID to arrange the way visual components should display information, but it seems only to support display for .gmp images, I already put in use the .jpeg library but no luck.
DBCtrol_grid_noJPG_SUPPORT.png
ASKER
Hie Mr Accalai, yes I could load the image, problem is as shown in the picture that I am using the DBCtrlGrid and then need DBImage component to list images from the Table, If I put a TImage component then all images will be the same.
And as far as I am concern, there is no way to load a .jpb into the DBImage component when is ON A DBCTRLGRID, if I am mistaken this is why I am requesting help.
And as far as I am concern, there is no way to load a .jpb into the DBImage component when is ON A DBCTRLGRID, if I am mistaken this is why I am requesting help.
I was speaking about TDBImage, not Timage. You can assign graphics to a dbimage pitcure also.
ASKER
When you try to load even at design time the component image from Blob Field, if the field on the table contains .BMP its ok if not, you get this error, anybody could answer with code?
Thanks
DBImage-Error-on-DBCtrlGrid.png
Thanks
DBImage-Error-on-DBCtrlGrid.png
Again, there're lot of examples around the web about this.
This is just one of the many results you can get, also on ExEx https://groups.google.com/forum/#!topic/borland.public.delphi.ide/BFDA6s8c2cY
This is just one of the many results you can get, also on ExEx https://groups.google.com/forum/#!topic/borland.public.delphi.ide/BFDA6s8c2cY
ASKER
Again, those codes are not working, could you do it yourself to see is not working?
Here is my code:
unit uTest;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.DBCtrls, Vcl.DBCGrids, Data.DB,
DBAccess, MyAccess, MemDS, Vcl.StdCtrls, jpeg, Vcl.ExtCtrls, cxGraphics,
cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxContainer, cxEdit,
cxTextEdit, cxDBEdit;
type
TForm3 = class(TForm)
db: TMyConnection;
qTemp: TMyQuery;
dsTemp: TMyDataSource;
DBCtrlGrid1: TDBCtrlGrid;
TImage1: TDBImage;
DBText1: TDBText;
DBText2: TDBText;
Image1: TImage;
DBImage1: TDBImage;
Button1: TButton;
qTempid: TIntegerField;
qTempupc: TStringField;
qTempaltupc: TStringField;
qTempbrand: TStringField;
qTempdescription: TStringField;
qTempsplit: TIntegerField;
qTempretail: TStringField;
qTempsalesSplit: TIntegerField;
qTempsalesRetail: TStringField;
qTempitemnumber: TStringField;
qTemppsize: TStringField;
qTempuom: TStringField;
qTempunitmea: TStringField;
qTempcaseqty: TIntegerField;
qTemppack: TIntegerField;
qTemppacksize: TStringField;
qTemppackweight: TStringField;
qTempunitprice: TStringField;
qTempunitcost: TFloatField;
qTempgroup_name: TStringField;
qTemppdate: TDateField;
qTempptime: TTimeField;
qTempfoodstamp: TStringField;
qTempwic: TStringField;
qTempwicvv: TStringField;
qTemptaxable: TStringField;
qTempscale: TStringField;
qTempdeposit: TStringField;
qTempdepositvalue: TStringField;
qTempcomments: TStringField;
qTemppicture: TStringField;
qTempactive: TStringField;
Label1: TLabel;
cxDBTextEdit1: TcxDBTextEdit;
DBImage2: TDBImage;
procedure qTempAfterScroll(DataSet: TDataSet);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure DBCtrlGrid1PaintPanel(DBCt rlGrid: TDBCtrlGrid; Index: Integer);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ShowJPG(FieldImagen:TBlobF ield; Picture:TPicture);
end;
var
Form3: TForm3;
JPegImage : TJpegImage; //A temporary JPeg
implementation
{$R *.dfm}
procedure TForm3.Button1Click(Sender : TObject);
begin
end;
procedure TForm3.DBCtrlGrid1PaintPan el(DBCtrlG rid: TDBCtrlGrid; Index: Integer);
Var
MyBlobStream : TBlobStream;
begin
// Do Only if a JPeg available
if (qTemp.FieldByName('Pictur e').IsBlob ) and (not(qTemp.FieldByName('Pi cture').Is Null)) then
begin
// Prepare Streams
MyBlobStream := TBlobStream.Create(TBlobFi eld(qTemp. FieldByNam e('Picture ')),bmRead );
JPegImage.LoadFromStream(M yBlobStrea m);
TImage1.Picture.Assign(JPe gImage);
MyBlobStream.Free; // Free Stream
end
else Timage1.Picture := Nil; // No JPeg saved disable display
end;
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
JPegImage.Free; // Free JPeg-Object
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
JpegImage := TJPegImage.Create; // Create JPeg-Object
qTemp.Open ;
end;
procedure TForm3.qTempAfterScroll(Da taSet: TDataSet);
Var
MyBlobStream : TBlobStream;
begin
// Do Only if a JPeg available
if (qTemp.FieldByName('pictur e').IsBlob ) and (not(qTemp.FieldByName('pi cture').Is Null)) then
begin
// Prepare Streams
MyBlobStream := TBlobStream.Create(TBlobFi eld(qTemp. FieldByNam e('Picture ')),bmRead );
JPegImage.LoadFromStream(M yBlobStrea m);
TImage1.Picture.Assign(JPe gImage);
MyBlobStream.Free; // Free Stream
end
else Timage1.Picture := Nil; // No JPeg saved disable display
end;
procedure TForm3.ShowJPG(FieldImagen : TBlobField; Picture: TPicture);
var
Stream: TMemoryStream;
Jpg : TJpegImage;
begin
Jpg := nil;
Stream := nil;
try
Stream := TMemoryStream.Create;
FieldImagen.SaveToStream(S tream);
if Stream.Size > 0
then
begin
Jpg := TJpegImage.Create;
Stream.Position := 0;
Jpg.LoadFromStream(Stream) ;
Picture.Assign(Jpg);
end
else Picture.Assign(nil);
except
Picture.Assign(nil);
end;
jpg.Free;
Stream.Free;
end;
end.
That code, generates NO ERRORS but images are not loaded.
ENPHASIS: "*.BMP images are are shown on Direct DBImage component over a DBCtrlGrid. Whoever responding to this, first test my code (just copy paste) and then express your opinions, I searched all possible solutions on the web and still cannot find it.
Thanks again.
NOTWORKING.jpg
Here is my code:
unit uTest;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.DBCtrls, Vcl.DBCGrids, Data.DB,
DBAccess, MyAccess, MemDS, Vcl.StdCtrls, jpeg, Vcl.ExtCtrls, cxGraphics,
cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxContainer, cxEdit,
cxTextEdit, cxDBEdit;
type
TForm3 = class(TForm)
db: TMyConnection;
qTemp: TMyQuery;
dsTemp: TMyDataSource;
DBCtrlGrid1: TDBCtrlGrid;
TImage1: TDBImage;
DBText1: TDBText;
DBText2: TDBText;
Image1: TImage;
DBImage1: TDBImage;
Button1: TButton;
qTempid: TIntegerField;
qTempupc: TStringField;
qTempaltupc: TStringField;
qTempbrand: TStringField;
qTempdescription: TStringField;
qTempsplit: TIntegerField;
qTempretail: TStringField;
qTempsalesSplit: TIntegerField;
qTempsalesRetail: TStringField;
qTempitemnumber: TStringField;
qTemppsize: TStringField;
qTempuom: TStringField;
qTempunitmea: TStringField;
qTempcaseqty: TIntegerField;
qTemppack: TIntegerField;
qTemppacksize: TStringField;
qTemppackweight: TStringField;
qTempunitprice: TStringField;
qTempunitcost: TFloatField;
qTempgroup_name: TStringField;
qTemppdate: TDateField;
qTempptime: TTimeField;
qTempfoodstamp: TStringField;
qTempwic: TStringField;
qTempwicvv: TStringField;
qTemptaxable: TStringField;
qTempscale: TStringField;
qTempdeposit: TStringField;
qTempdepositvalue: TStringField;
qTempcomments: TStringField;
qTemppicture: TStringField;
qTempactive: TStringField;
Label1: TLabel;
cxDBTextEdit1: TcxDBTextEdit;
DBImage2: TDBImage;
procedure qTempAfterScroll(DataSet: TDataSet);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure DBCtrlGrid1PaintPanel(DBCt
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ShowJPG(FieldImagen:TBlobF
end;
var
Form3: TForm3;
JPegImage : TJpegImage; //A temporary JPeg
implementation
{$R *.dfm}
procedure TForm3.Button1Click(Sender
begin
end;
procedure TForm3.DBCtrlGrid1PaintPan
Var
MyBlobStream : TBlobStream;
begin
// Do Only if a JPeg available
if (qTemp.FieldByName('Pictur
begin
// Prepare Streams
MyBlobStream := TBlobStream.Create(TBlobFi
JPegImage.LoadFromStream(M
TImage1.Picture.Assign(JPe
MyBlobStream.Free; // Free Stream
end
else Timage1.Picture := Nil; // No JPeg saved disable display
end;
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
JPegImage.Free; // Free JPeg-Object
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
JpegImage := TJPegImage.Create; // Create JPeg-Object
qTemp.Open ;
end;
procedure TForm3.qTempAfterScroll(Da
Var
MyBlobStream : TBlobStream;
begin
// Do Only if a JPeg available
if (qTemp.FieldByName('pictur
begin
// Prepare Streams
MyBlobStream := TBlobStream.Create(TBlobFi
JPegImage.LoadFromStream(M
TImage1.Picture.Assign(JPe
MyBlobStream.Free; // Free Stream
end
else Timage1.Picture := Nil; // No JPeg saved disable display
end;
procedure TForm3.ShowJPG(FieldImagen
var
Stream: TMemoryStream;
Jpg : TJpegImage;
begin
Jpg := nil;
Stream := nil;
try
Stream := TMemoryStream.Create;
FieldImagen.SaveToStream(S
if Stream.Size > 0
then
begin
Jpg := TJpegImage.Create;
Stream.Position := 0;
Jpg.LoadFromStream(Stream)
Picture.Assign(Jpg);
end
else Picture.Assign(nil);
except
Picture.Assign(nil);
end;
jpg.Free;
Stream.Free;
end;
end.
That code, generates NO ERRORS but images are not loaded.
ENPHASIS: "*.BMP images are are shown on Direct DBImage component over a DBCtrlGrid. Whoever responding to this, first test my code (just copy paste) and then express your opinions, I searched all possible solutions on the web and still cannot find it.
Thanks again.
NOTWORKING.jpg
Jose,
I used a TImage component
and just this piece of code: (my image is in the column IMG)
I used a TImage component
and just this piece of code: (my image is in the column IMG)
implementation
uses Jpeg;
{$R *.dfm}
procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid; Index: Integer);
var JI: TJPEGImage;
fld: TField;
bs: TBlobStream;
begin
fld := DBCtrlGrid.DataSource.DataSet.FieldByName('IMG');
if not fld.IsNull and fld.IsBlob then
begin
Ji := TJPegImage.Create;
try
bs := TBlobStream.Create(TBlobField(fld), bmRead);
try
ji.LoadFromStream(bs);
ji.DIBNeeded;
Image1.Picture.Assign(ji);
finally
bs.Free;
end;
finally
Ji.Free;
end;
end;
end;
hmmm, seems you copied from Kretschmar's code:
https://www.experts-exchange.com/questions/10175461/JPG-Images-into-TDBCtrlGrid.html
odd that he uses a component with a global scope for that
for your code, some remarks:
your getting warnings ? object not initialized
that's because you use the try finally block in a wrong way
and you probably have memory leaks
There is no point in setting Jpg and Stream := nil
It just removes the warning, but doesn't solve the problem > potential memory leak
Try should come after the create
and the free should be wrapped in a finally end
you get an access violation when stream.size = 0
when executing jpg.Free
https://www.experts-exchange.com/questions/10175461/JPG-Images-into-TDBCtrlGrid.html
odd that he uses a component with a global scope for that
for your code, some remarks:
your getting warnings ? object not initialized
that's because you use the try finally block in a wrong way
and you probably have memory leaks
Jpg := nil;
Stream := nil;
try
Stream := TMemoryStream.Create;
FieldImagen.SaveToStream(Stream);
There is no point in setting Jpg and Stream := nil
It just removes the warning, but doesn't solve the problem > potential memory leak
Try should come after the create
and the free should be wrapped in a finally end
Jpg := TJpegImage.Create;
try
// do something
finally
jpg.Free;
end;
you get an access violation when stream.size = 0
when executing jpg.Free
ASKER
I need specifically to use TDBImage to load it, remember this guys. No body is pointing straight to the problem, focus on the issue not on my coding, again "WHY DBIMAGE only shows .bmp image when is on a DBCTRLGrid.
no you don't :)
as it doesn't work with a TDBImage, we all provide a workaround.
certain components are built by borland and why they were so narrow minded about this, i don't know
in principal, you could do the following:
* convert the image to a .bmp upon uploading it to the database (same technique as shown)
* store the .bmp it in a secondary blob and show that secondary blob column via the TDBImage
as it doesn't work with a TDBImage, we all provide a workaround.
certain components are built by borland and why they were so narrow minded about this, i don't know
in principal, you could do the following:
* convert the image to a .bmp upon uploading it to the database (same technique as shown)
* store the .bmp it in a secondary blob and show that secondary blob column via the TDBImage
if you don't believe me, which i follow ...
attempted this:
https://delphihaven.wordpress.com/2011/01/22/tip-detecting-graphic-formats/
the bottomline is: TPicture doesn't have a LoadFromStream
> it uses registered file extensions and LoadFromFile to determine the picture graphic class
I attempted an old trick:
Copy a Borland/Embarcadero source file: Vcl.DBCtrls.pas to the project directory and modify it
> I added virtual to the TDBImage.LoadPicture method so i could override it in a descendant
procedure LoadPicture; virtual;
alas, all my attempts fail
this is my source code:
als, that trick doesn't work anymore
attempted this:
https://delphihaven.wordpress.com/2011/01/22/tip-detecting-graphic-formats/
the bottomline is: TPicture doesn't have a LoadFromStream
> it uses registered file extensions and LoadFromFile to determine the picture graphic class
I attempted an old trick:
Copy a Borland/Embarcadero source file: Vcl.DBCtrls.pas to the project directory and modify it
> I added virtual to the TDBImage.LoadPicture method so i could override it in a descendant
procedure LoadPicture; virtual;
alas, all my attempts fail
this is my source code:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Data.DB,
DBAccess, Ora, OraCall, MemDS, Vcl.DBCGrids;
type
TBDImage = class(Vcl.DBCtrls.TDBImage)
public
procedure LoadPicture; override;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
DBCtrlGrid1: TDBCtrlGrid;
DBText1: TDBText;
DBImage1: TDBImage;
OraQuery1: TOraQuery;
OraSession1: TOraSession;
OraDataSource1: TOraDataSource;
Image1: TImage;
procedure FormShow(Sender: TObject);
private
procedure AddMsg(Msg: string);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses GIFImg, JPEG, PngImage;
{$R *.dfm}
const
MinGraphicSize = 44; //we may test up to & including the 11th longword
SInvalidImage = 'Invalid image';
function FindGraphicClass(const Buffer; const BufferSize: Int64;
out GraphicClass: TGraphicClass): Boolean; overload;
var
LongWords: array[Byte] of LongWord absolute Buffer;
Words: array[Byte] of Word absolute Buffer;
begin
GraphicClass := nil;
Result := False;
if BufferSize < MinGraphicSize then Exit;
case Words[0] of
$4D42: GraphicClass := TBitmap;
$D8FF: GraphicClass := TJPEGImage;
$4949: if Words[1] = $002A then GraphicClass := TWicImage; //i.e., TIFF
$4D4D: if Words[1] = $2A00 then GraphicClass := TWicImage; //i.e., TIFF
else
if Int64(Buffer) = $A1A0A0D474E5089 then
GraphicClass := TPNGImage
else if LongWords[0] = $9AC6CDD7 then
GraphicClass := TMetafile
else if (LongWords[0] = 1) and (LongWords[10] = $464D4520) then
GraphicClass := TMetafile
else if StrLComp(PAnsiChar(@Buffer), 'GIF', 3) = 0 then
GraphicClass := TGIFImage
else if Words[1] = 1 then
GraphicClass := TIcon;
end;
Result := (GraphicClass <> nil);
end;
function FindGraphicClass(Stream: TStream;
out GraphicClass: TGraphicClass): Boolean; overload;
var
Buffer: PByte;
CurPos: Int64;
BytesRead: Integer;
begin
if Stream is TCustomMemoryStream then
begin
Buffer := TCustomMemoryStream(Stream).Memory;
CurPos := Stream.Position;
Inc(Buffer, CurPos);
Result := FindGraphicClass(Buffer^, Stream.Size - CurPos, GraphicClass);
Exit;
end;
GetMem(Buffer, MinGraphicSize);
try
BytesRead := Stream.Read(Buffer^, MinGraphicSize);
Stream.Seek(-BytesRead, soCurrent);
Result := FindGraphicClass(Buffer^, BytesRead, GraphicClass);
finally
FreeMem(Buffer);
end;
end;
procedure LoadPictureFromBlobField(Field: TBlobField; Dest: TPicture);
var
Graphic: TGraphic;
GraphicClass: TGraphicClass;
Stream: TMemoryStream;
begin
Graphic := nil;
Stream := TMemoryStream.Create;
try
Field.SaveToStream(Stream);
if Stream.Size = 0 then
begin
Dest.Assign(nil);
Exit;
end;
if not FindGraphicClass(Stream.Memory^, Stream.Size, GraphicClass) then
raise EInvalidGraphic.Create(SInvalidImage);
Graphic := GraphicClass.Create;
Stream.Position := 0;
Graphic.LoadFromStream(Stream);
Dest.Assign(Graphic);
finally
Stream.Free;
Graphic.Free;
end;
end;
procedure Tform1.AddMsg(Msg: string);
begin
Memo1.Lines.Insert(0, Msg);
end;
procedure TForm1.FormShow(Sender: TObject);
begin
end;
{ TBDImage }
procedure TBDImage.LoadPicture;
begin
if Assigned(Field) and not Field.IsNull and Field.IsBlob then
begin
LoadPictureFromBlobField(TBlobField(Field), Picture);
end;
end;
end.
als, that trick doesn't work anymore
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Anyway JVCL TJVDBImage supports JPEG format, and also you can register other formats like png or tiff