how can I convert a byte image to a png image lazarus / 39-Graphics ---------------------------------------------------------------------- Informaticien · 2012-07-03 12:15 Hello, I use Lazarus v1.1 on windows 7, I have a result from request from a column image (sql server), my query is like that : Code: [Select]SELECT TOP 1 [Item].[ItemImage] AS image FROM [Item] WHERE [Item].[ItemImage] IS NOT NULLThe problem is than my result is like that : Code: [Select]0x89504E470D0A1A0A0000000D494844520000013B000000FA080600 0000DE1FE0620000000467414D410000AFC837058AE90000001974455874536F667477 6172650041646F626520496D616765526561647971C9653C000039F649444154785EED 9D07581557DEC679BEBEFBED7E9B4D36BD6BECBD60A7F72228A0144 etc...I don't know how can i make a image with that, i'm sure this code can make a image to png format but how? I don't know. Someone can help me? My code is like that : Code: [Select] procedure TForm1.Button2Click(Sender: TObject); Var   connexion: TZConnection;   QueryData: TZQuery;   datasource: TDataSource;   fstream : tStream;   CopyBMP: TBitmap; begin   connexion:= TZConnection.Create(nil);   QueryData:= TZQuery.Create(nil);   datasource:= TDataSource.Create(nil);   connexion.HostName:='localhost\myserver';   connexion.Protocol:='mssql';   connexion.User:='sa';   connexion.Password:='@ccre47ds';   connexion.Connected:=True;   QueryData.Connection:= connexion;   QueryData.SQL.Text:='USE [Demo4.cdscdsdc_cdsqcdsq_cdsqcdsq_cdsqcdsq];'+#13#10+   ' SELECT TOP 1 [Item].[ItemImage] AS image FROM [Item] WHERE [Item].[ItemImage] IS NOT NULL';   QueryData.Open;   datasource.DataSet:= QueryData;   try     fstream:= QueryData.CreateBlobStream(QueryData.FieldByName('image'), bmread);     // here, i don't know what to do ;-(   except     on E: Exception do       Memo1.Text:=E.message;   end; end; ---------------------------------------------------------------------- ludob · 2012-07-03 12:55 Do you want to display the image or save it to a file? When displaying, the easiest is to use TDBImage. You assign the datasource and the fieldname and you are done. To save to a file just do Code: [Select]DBImage1.Picture.PNG.SaveToFile(Filename);  Another approach is to use a TPicture and do Code: [Select]picture.LoadFromStream(fstream); ---------------------------------------------------------------------- Informaticien · 2012-07-03 13:18 thank for your reply, so now my code is : Code: [Select] procedure TForm1.Button2Click(Sender: TObject); Var   connexion: TZConnection;   QueryData: TZQuery;   datasource: TDataSource;   fstream : tStream;   DBImage2: TDBImage; begin   connexion:= TZConnection.Create(nil);   QueryData:= TZQuery.Create(nil);   datasource:= TDataSource.Create(nil);   connexion.HostName:='localhost\myserver';   connexion.Protocol:='mssql';   connexion.User:='sa';   connexion.Password:='@cezcez';   connexion.Connected:=True;   QueryData.Connection:= connexion;   QueryData.SQL.Text:='USE [Demo4.cdscds_cdscds_cdscsd_cs];'+#13#10+   ' SELECT TOP 1 [Item].[ItemImage] AS image FROM [Item] WHERE [Item].[ItemImage] IS NOT NULL';   QueryData.Open;   datasource.DataSet:= QueryData;   try     fstream:= QueryData.CreateBlobStream(QueryData.FieldByName('image'), bmread);     DBImage2.Create(nil);     DBImage2.Picture.LoadFromStream(fstream);     DBImage2.Picture.PNG.SaveToFile('C:\Users\jb\Documents\WebMasterT\ images\file.png');     fstream.Free;     DBImage2.Free;   except     on E: Exception do       Memo1.Text:=E.message;   end; end;       The probleme then i have a access violation and my picture don't exists on the path, do you know why. ---------------------------------------------------------------------- Informaticien · 2012-07-03 13:22 And when i try to do : Code: [Select]DBImage1.Picture.LoadFromStream(fstream); where DBImage1 is a component on my form i have this error : Chunk length exceeds stream length ---------------------------------------------------------------------- ludob · 2012-07-03 15:11 The last error probably indicates that the data retrieved from the database is not complete. Try storing the file immediately without going through the TPicture conversion and load it with an external program to see if the file is complete: Code: [Select]  QueryData.Open; TBlobField(QueryData.FieldByName('image')).SaveToFile('C:\Users\jb\Doc uments\WebMasterT\images\file.png'); No fstream needed. ---------------------------------------------------------------------- Informaticien · 2012-07-03 15:20 Ok, thanks a lot, that work but not perfectly because my image is not whole, have you a idea why it's like that? Thank ;-) ---------------------------------------------------------------------- ludob · 2012-07-03 15:41 Or the data is not in the database or it could not be read completely. Do a Code: [Select]select datalength([Item].[ItemImage]) from [Item] WHERE [Item].[ItemImage] IS NOT NULL in your database and check the returned value with the length of the png file. If they are the same, the data in the database is truncated. How is the field 'image' defined? What version of ZeosLib are you using? Is it using DBLIB or ADO to connect to sqlserver? ---------------------------------------------------------------------- Informaticien · 2012-07-03 15:54 Code: [Select]select datalength([Item].[ItemImage]) from [Item] WHERE [Item].[ItemImage] IS NOT NULL : 14948, i don't think the value is truncated because the soft use this field can show the image correctly (it's the same). I use zeos svn, and i install lazarus there are not a long time, just two week, so i think i have the last version. The field image is defined into database like a image column type. I use DBLIB for connect to sql server (i think) in my unit form i uses this : Code: [Select]Classes, SysUtils, db, FileUtil, Forms, Controls, Graphics, Dialogs, dbctrls,   StdCtrls, ZDataset, ZConnection, FPimage, FPCanvas, FPImgCanv,   FPWritePNG; nothing more. if i do Code: [Select]fstream.Sizei have 4096 if i do Code: [Select]QueryData.FieldByName('image').Sizei have 0 and if i do Code: [Select]QueryData.FieldByName('image').AsStringi have "?PNG" Many thank for your reply, it's very cool ;-) ---------------------------------------------------------------------- ludob · 2012-07-03 16:53 There seems to be a problem in how Zeos is using dblib. The data length returned for the blob field is limited to 4096. I tried also with mssqlconnection in fcl-db that uses also dblib and it returns the complete data. Tried also with Zeos and a mysql connection and that doesn't have the 4096 byte limitation either. I'm investigating this further and will keep you updated. ---------------------------------------------------------------------- Informaticien · 2012-07-03 17:12 ok, thank a lot, i hope this problem will be solved a few time, there was my last dev for finish my programm... hahaha... I'm no fortunate ;-). I'll see this page sometimes for see if something change... ---------------------------------------------------------------------- ludob · 2012-07-04 08:30 Got it There is a mix-up in the definition of the constant DBTEXTLIMIT for ntwdblib.dll. Recently Zeos cleaned up the constants but made another mistake. Depending on what version of zeos you are using make the following change: Code: [Select]Index: src/plain/ZPlainDbLibConstants.pas =================================================================== --- src/plain/ZPlainDbLibConstants.pas  (revision 1370) +++ src/plain/ZPlainDbLibConstants.pas  (working copy) @@ -120,7 +120,7 @@    DBOFFSET              = 1;    DBROWCOUNT            = 2;    DBSTAT                = 3; -  DBTEXTLIMIT           = 7; +  DBTEXTLIMIT           = 4;    DBTEXTSIZE            = 17;    DBARITHABORT          = 6;    DBARITHIGNORE         = 7; Or this one (latest svn form today): Code: [Select]Index: src/dbc/ZDbcDbLib.pas =================================================================== --- src/dbc/ZDbcDbLib.pas       (revision 1435) +++ src/dbc/ZDbcDbLib.pas       (working copy) @@ -459,7 +459,7 @@    DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);    LogMessage := 'set textlimit=2147483647'; -  if GetPlainDriver.dbsetopt(FHandle, GetPlainDriver.GetVariables.dboptions[Z_TEXTSIZE] , '2147483647') <> DBSUCCEED then +  if GetPlainDriver.dbsetopt(FHandle, GetPlainDriver.GetVariables.dboptions[Z_TEXTLIMIT] , '2147483647') <> DBSUCCEED then      CheckDBLibError(lcConnect, LogMessage);    DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage); If non of these patches match your version just hard-code the DBTEXTLIMIT  constant in TZDBLibConnection.Open (src/dbc/ZDbcDbLib.pas) and change the line to : Code: [Select]  if GetPlainDriver.dbsetopt(FHandle, 4, '2147483647') <> DBSUCCEED then ---------------------------------------------------------------------- Informaticien · 2012-07-04 09:33 ok, thank! Do i need to rebuild lazarus after? If yes how? Because wiki.freepascal.org is inaccessible today... Thank ---------------------------------------------------------------------- ludob · 2012-07-04 09:42 You don't have to. The package will be recompiled automatically and the new code will be used in your program. If you need the new code in lazarus (to preview DBImage in the IDE for example) you have to rebuild Lazarus. Just go to Tools/Build Lazarus with Profile: xyz . ---------------------------------------------------------------------- Informaticien · 2012-07-04 10:18 Ok, very good job, thank a lot, i needed to do Code: [Select]if GetPlainDriver.dbsetopt(FHandle, 4, '2147483647') <> DBSUCCEED thenAnd my picture is create like i want, perfectly!!!