DBImage loading from blob lazarus / 16-Databases ---------------------------------------------------------------------- teos · 2012-09-09 10:52 Hello All, I have a question about the DBImage component, because I read that the Lazarus DBImage is not compatible with the Delphi one. And I don't understand why the code is the way it is, introducing the problems it does, but without an (for me) obvious reason. My tought: a TImage can load a picture from either file or stream. So it must have the logics to determine what kind of image it reads. That logic is in TPicture. I find a few things I don't understand but I think there is a reason for doing so: 1. TDBImage.LoadPicture uses a TPicture internally but instead of TDBImage.Picture.Loadfromstream a TGraphic is created, which has to determine what kind of image to read. Why? Because the code as I modified it can read the image from the blob field without further checks, because those checks are in picture.        try           picture.LoadFromStream(s);         finally           s.Free;         end {try} My question: does anyone know why the TDBImage code has the extra code like below? IMHO all it does is break compatibility with Delphi...           GraphExt :=  s.ReadAnsiString;           if GraphExt = '' then GraphExt := 'jpg';           gc := GetGraphicClassForFileExtension(GraphExt);           if assigned(gc) then             begin             AGraphic := gc.Create;             AGraphic.LoadFromStream(s);             Picture.Assign(AGraphic);             end; ---------------------------------------------------------------------- Lacak2 · 2012-09-10 06:18 Good question  It seems, that every Image descendant supports class function IsStreamFormatSupported, which checks stream data to detect known "image signature" ... clever solution. IMO this approach can also be used in TDBImage ... ---------------------------------------------------------------------- taazz · 2012-09-10 08:04 because it is a well behaved easy to check and correct if anything goes wrong and also easy to duplicate in other environments that being C/C++, delphi, rudy or java and it is far better than the one used by delphi, where an integer constant was used, were to support more image types you had  to subclass the DBIMage component it self. In any case I find it extremely well thought. This enables not so experienced developers to use existing libraries to add support for an image type (through a dll for example) with out to much work or delving to deep in the images details and any one to debug and correct recognition problems  with out the requirement of knowing the internals of each image type which in some cases might not be public knowledge. It is far better this way although it does create some small problems with other environments it is easy to just ignore the first X bytes of the stream and load the image as they see fit. ---------------------------------------------------------------------- teos · 2012-09-10 19:55 I would say that someone overlooked that there is another way to determine what kind of picture is in the stream that try to use the "GetGraphicClassForFileExtension" approach that checks for a FILE extension. TPicture.Loadfromstream uses the same approach but based on the contents of the stream. @Taazz: I hope you know that graphic files have a signature that is also written to the blob that TDBImage reads. I agree with your opinion. But I don't agree on the extremely well thought behaviour you think DBImage has: the error handling you mention is not there: if not everything works as expected (no extension in the stream), the DBImage does not show anything, because there is no fallback that tries to determine the image type from the stream. And a second issue: The code as I posted, is compatible not only with other programming tools but there is no database management tool which writes the extension in a blob field. So using one of those tools or the combination of Lazarus with anything else only causes problems because of the different way lazarus handles blob images. But besided that: I was not after the differences, I was wondering if the programmer of TDBImage missed that the TPicture he assignes the image to is perfectly capable of loading that image with a fallback. (I wondered if the code is backward compatible or makes something platform independant or whatever). And sorry: I'm not trying to be the "know it all", running into the problem that TDBImage did not display a picture whatsoever. SQLite Expert seemed not capable of writing a readable image, so I did a little investigation, finding what caused me to post this question. Just after changing DBImage to what I have, images are visibile when I add them from something different than TDBImage (because TBlobfield does not write that signature too..) [EDIT] And I wonder why "Removed in 0.9.29. DB control should not save/load their data from stream" is there and why. [/EDIT] ---------------------------------------------------------------------- teos · 2012-09-10 20:11 Quote from: taazz on September 10, 2012, 10:04:31 amIn any case I find it extremely well thought. This enables not so experienced developers to use existing libraries to add support for an image type (through a dll for example) with out to much work or delving to deep in the images details and any one to debug and correct recognition problems  with out the requirement of knowing the internals of each image type which in some cases might not be public knowledge. existing libraries won't read images added by Lazarus DBImage and won't write blob fields that Lazarus DBImage is able to read. Fun is: Lazarus TDBImage is the only with the funny file extension extra.. If there were no alternatives, OK. But there is one that takes the hassle away from the programmer. I have never looked at Delphi TDBImage sources because it works and without anything extra. Lazarus BlobStream does not read or write the extension, so it's up to the (beginning) programmer to take care of the correct extension and the correct format of that extension in the blob field, meaning digging into dbimage.inc anyway. I choose the out of the box solution if that's OK ---------------------------------------------------------------------- taazz · 2012-09-10 21:26 I am sorry I find a bit dificult to follow probably because my head spins at the moment. TDBImage uses TBlobStream to save image data in to Image and BLOB fields. Most databases do no an Image field type just a blob when you use the TBlobstream you can save the image data with out the extra image recognition bytes that blobimage adds and tries to find. In this form all other programs should be able to read those data and try to show them and fail because most other program support only bmp/jpg/gif and maybe png what happens if the data format is a medical image format? Using DBImage to save and load the image from the blob field dbimage adds the extra bytes required to read the image correctly the next time and on read guides the image reading classes where to start reading to aboid problems. That's it. begging programmers do not need to know how to add support for dbimage they just use it and it works. All other programmers should either adapt or move on, so should you. Again I find the current design elegant and to the point. it is easy to bypass if needed just dont use dbimage. ---------------------------------------------------------------------- goodname · 2012-09-10 22:48 Have looked at this in the past. Decided not to use DBImage as it did not seam to work and didn't put the effort to figure out why.  Used TImage with SQLdb, afterScroll events, and TPicture.LoadFromStream. Read something about non-standard way of identifying image type which makes the saved file incompatible with other programs reading the file. TPicture.LoadFromStream seams to use the commonly recognized magic number/signature method so saved file is compatible with other programs. http://www.lazarus.freepascal.org/index.php/topic,17606.msg97420.html# msg97420 ---------------------------------------------------------------------- joseme · 2012-09-11 12:37 You should even consider if it is no more convenient to keep your image in a separate file rather than storing it in a blob. There are performance considerations, as stated in http://www.revsys.com/blog/2012/may/01/three-things-you-should-never- put-your-database/ My two cents ---------------------------------------------------------------------- goodname · 2012-09-11 13:16 Images in the database will likely be slower on read/write and can cause the database backup to grow large. The article does not mention the advantages to putting images in a database. Images are backed up with the database. There is no need to worry about unique file names. You have to go through the database to figure out what image links with what record any way. Be aware of the pros and cons and know your system needs. ---------------------------------------------------------------------- teos · 2012-09-11 18:00 Quote from: goodname on September 11, 2012, 12:48:20 amHave looked at this in the past. Decided not to use DBImage as it did not seam to work and didn't put the effort to figure out why.  Used TImage with SQLdb, afterScroll events, and TPicture.LoadFromStream. Read something about non-standard way of identifying image type which makes the saved file incompatible with other programs reading the file. TPicture.LoadFromStream seams to use the commonly recognized magic number/signature method so saved file is compatible with other programs. http://www.lazarus.freepascal.org/index.php/topic,17606.msg97420.html# msg97420 Yes Tpicture reads the magic number from the stream. That is my point in this. If TPicture reads the signature why is that not the way tdbimage not using that? Even more because my modification lets the component work like it should.  Store images in files or blobs is another discussion. In this case I have a solution for a not working component and I wonder if that is interesting for others too ---------------------------------------------------------------------- Lacak2 · 2012-09-12 05:32 Yes, IMO at lest there should be property of TDBImage which will control how image data will be streamed in/out blobs. With extension prefix or without (then image type will be detected on signature in stream). ---------------------------------------------------------------------- KpjComp · 2012-09-12 09:05 Quote from: goodname on September 11, 2012, 03:16:49 pmThe article does not mention the advantages to putting images in a database. Totally agree,.. Another advantage, is if in a C/S multi-user database if you don't store them within blobs, this means your going to have to store them somewhere else, eg. a Share.  For me this takes away DB integrity, an opens more security holes. The reasons against that @joseme showed a link too, I actually find lame. Quoteread/write to a DB is always slower than a filesystem Is it?, at the end of the day if your images have to be shared in a multi-user environment, then transfer of image data is exactly the same speed, it's still going over a network.  Unless the DB engine causes massive overhead, but it shouldn't. Quoteyour DB backups grow to be huge and more time consuming Are the images not important?..  Quoteaccess to the files now requires going through your app and DB layers That's an advantage, not a disadvantage.  If you want to access your images via a Webserver etc, it's still easy. ---------------------------------------------------------------------- ludob · 2012-09-12 09:56 As usual this is not a black and white situation and it depends on the usage of the database. Quoteat the end of the day if your images have to be shared in a multi-user environment, then transfer of image data is exactly the same speed, it's still going over a network.  Unless the DB engine causes massive overhead, but it shouldn't.Correct, but when stored in a database, the row/table is locked for the full length of the data transfer which can affect multi-user performance. Depending on the transaction isolation, multiple temporary copies of the image can float around for rollback, versioning, etc. Some databases (fe. firebird) can grow quite quickly because of the garbage left behind. A lot depends also on how the database is designed. A separate table for images is obviously much better than adding a blob as the 20th field in an already overloaded table. If the db supports it you can then also put that table on a different volume (tablespace) and define different backup frequency and media. Hybrid solutions like Oracle's BFILE data type is using the best of both worlds: files are stored on a file system and are accessible as a blob through the oracle client. ---------------------------------------------------------------------- KpjComp · 2012-09-12 10:37 QuoteCorrect, but when stored in a database, the row/table is locked for the full length of the data transfer which can affect multi-user performance. Not the way I use them. For starters, most access to to images inside a DB for me are Read- Only.  This means you can access the images in Snapshot transaction mode, this means there is no locking involved.  And for when locking is involved when writing, the Blob, then that's what you want anyway, if integrity is important. Like you said, keeping images inside a separate file, is also a good idea. QuoteHybrid solutions like Oracle's BFILE Yes, NexusDB is another one that can proxy the blobs. ---------------------------------------------------------------------- goodname · 2012-09-12 13:33 I suspect that the author of the "don't put images in the database" article deals with web pages. In that case it makes sense to just hold a path to the file as the images will be loaded later by a tag. File systems are designed to handle files. That is about all they do. A database uses the underlying file system to hold blobs. For raw read and write the best a database can hope for is to add minimal overhead. I think that DBImage should be able to handle images using signatures as well. It looks like it would be a simple patch. The only complicated part being an option to handle backward compatibility. ---------------------------------------------------------------------- KpjComp · 2012-09-12 15:55 QuoteI suspect that the author of the "don't put images in the database" article deals with web pages. That's what I do, and still use the tag.  On a website the tag isn't just hard coded to filesystem access.  Another advantage here is then it's much easer to control other aspects of Images on websites, like expiry dates / Cache control etc.  I usually also do some back-end processing, like auto scaling the images for thumbnail view etc.  So for dynamic websites I find DB Image Blobs much more flexible than dumb files. So like I said, the author of that link saying you should never put images in database blobs, is just wrong. ---------------------------------------------------------------------- teos · 2012-09-12 21:22 Wether to store a image in a database is not only another discussion but IMHO not relevant for my question :-) But I would not keep separate images next to a database. AFAIK a well designed database indeed keeps the blobs in a separate table or the developer constructs SQL where the blob is fetched later (maybe in master-detail). I have nothing against an extra property to keep everybody happy. What I know for sure is that TBlobfield will not store an extra signature in a blob field, nor read it. But I suppose tblobfield is the most used for getting an image in a blob field. I repeat: If you load an image from file or clipboard, the stream allready has information about the file format. My conclusion is that the TDBImage.Picture should load the image itself and somebody was either not aware of the TPicture capabilities or did not understand that the signature of a graphics file is in the file itself. But at this point comes the next question: how do I contact the author of TDBImage to get the modification in the component for the next Lazarus release? ---------------------------------------------------------------------- taazz · 2012-09-12 22:47 the problem is no the signature of the image file which might or might not exists because in most cases it exists. The problem is that the magic number usually is not a number but a series of numbers in various positions on the header. Blob managing comes in blocks you never read the entire blob in one step it has  to be broken down in multiple steps. How many steps will require depends heavily on the underline dll (fbclient, pgXXX etc). Adding few extra bites in the begging of the stream makes sure that what ever the block size of blob operation is the component will know if it can load the data on the first packet stopping any farther communication which might take a while depending on the blob size. There are people that use the database to store images that can be 100s of MB. As long as there is an option to disable/enable the current behavior that would be fine I guess. In any case you need to post a new feature request in the bug tracker and some one that knows how to change will be appointed to. ---------------------------------------------------------------------- KpjComp · 2012-09-12 23:17 The one problem I see with magic number's, is that in theory they could be a potential for overlap.  Eg, you could maybe have a JPeg file that just happens to have the same signature for a BMP at the BMP signature position, or vice versa.  The problem is magic numbers are not a standard between graphics formats. The chances of misreading a magic number of course is small, but in theory possible.  If you add into the mix more file types, eg. RAW/GIF/TIFF etc the chances of a overlap are even more. This is also more than likely the reason why TPicture.LoadFromFile first uses extension, rather than just passing along to LoadFromStream and checking the magic numbers. ---------------------------------------------------------------------- teos · 2012-09-13 09:04 Quote from: KpjComp on September 13, 2012, 01:17:38 amThe one problem I see with magic number's, is that in theory they could be a potential for overlap.  Eg, you could maybe have a JPeg file that just happens to have the same signature for a BMP at the BMP signature position, or vice versa.  The problem is magic numbers are not a standard between graphics formats. The only flaw I see is writing a file extension as signature to a stream. Because in the current situation the code just assumes that the signature is right and tries to read the stream. QuoteThe chances of misreading a magic number of course is small, but in theory possible.  If you add into the mix more file types, eg. RAW/GIF/TIFF etc the chances of a overlap are even more. This is also more than likely the reason why TPicture.LoadFromFile first uses extension, rather than just passing along to LoadFromStream and checking the magic numbers. Yes, and using that file extension (which could also be blank or something different than the actual graphic format) is the only flaw TPicture.Loadfromfile has. I wonder why we are having discussions like that: If you open a JPG file with a text or hex editor, you see that in the first bytes of the file the graphic format is written. And that will not be different from the actual file type. Same applies for all other graphic formats. I must say that I'm surprised by the doubts that graphic files have a unique identifier in the first bytes and storing a file extension to determine the kind of graphic is not needed by any means. But anyway, I will post a change request. Thank you all for replying. That is highly appericiated. ---------------------------------------------------------------------- BigChimp · 2012-09-13 09:13 Quote from: teos on September 13, 2012, 11:04:30 amI must say that I'm surprised by the doubts that graphic files have a unique identifier in the first bytes and storing a file extension to determine the kind of graphic is not needed by any means. But anyway, I will post a change request. Thank you all for replying. That is highly appericiated. You might want to refer to bug: http://bugs.freepascal.org/view.php?id=22416 and of course, adding a patch will make it more likely to get this implemented ---------------------------------------------------------------------- KpjComp · 2012-09-13 09:56 QuoteI wonder why we are having discussions like that If you don't understand why, then I'll keep out.   bye.. ---------------------------------------------------------------------- teos · 2012-09-13 10:22 Quote from: KpjComp on September 13, 2012, 11:56:01 amQuoteI wonder why we are having discussions like that If you don't understand why, then I'll keep out.   bye.. I was referring to the discussion about signatures in general, making the mistake to think we all are experienced enough to have an idea about graphic files and the mentioned signature. Whatever I say or remark, it's never a personal attack. Sorry if it looked that way. ---------------------------------------------------------------------- teos · 2012-09-13 10:24 Quote from: BigChimp on September 13, 2012, 11:13:31 amQuote from: teos on September 13, 2012, 11:04:30 amI must say that I'm surprised by the doubts that graphic files have a unique identifier in the first bytes and storing a file extension to determine the kind of graphic is not needed by any means. But anyway, I will post a change request. Thank you all for replying. That is highly appericiated. You might want to refer to bug: http://bugs.freepascal.org/view.php?id=22416 and of course, adding a patch will make it more likely to get this implemented I have filed a ticket. http://mantis.freepascal.org/view.php?id=22870, now looking how to change it so the refrerence can be added. ---------------------------------------------------------------------- tonyw · 2012-10-16 14:21 I have uploaded a patch as a response to http://bugs.freepascal.org/view.php?id=22416. This should add the means to override the default behaviour of TDBImage and allow for other means of identifying the BLOB image type. An example of use is included with my response to the bug. ---------------------------------------------------------------------- José Mejuto · 2012-10-16 20:44 Quote from: KpjComp on September 13, 2012, 01:17:38 amThe chances of misreading a magic number of course is small, but in theory possible.  If you add into the mix more file types, eg. RAW/GIF/TIFF etc the chances of a overlap are even more. Hello, The graphics formats are all of them selectable using the first 16 bytes, except RAW which by definition is not s graphic format as it is a two pieces information packet, how to interpret the data and the data. QuoteThis is also more than likely the reason why TPicture.LoadFromFile first uses extension, rather than just passing along to LoadFromStream and checking the magic numbers. The extension was set because there were not a function to identify graphics formats by they "magic numbers". ---------------------------------------------------------------------- KpjComp · 2012-10-17 12:05 QuoteThe graphics formats are all of them selectable using the first 16 bytes So you know for sure that there is no potential of an overlap with all Image formats, & using magic numbers is 100% correct. So JPG/TIFF/GIF/PNG/PPM/PGM/PBM/PNM/WEBP/HDR/RGBE/IFF-RGFX/TGA/ILBM/IM G/PCX/ECW/IMG/SID/CD5/FITS/PGF/XCF/PSD/PSP/CGM/SVG/CDR/AI/PPT/VML/XPS etc/etc..  All these formats in no way could have magic numbers embedded within them from other formats causing a mismatch, or that every format even has a magic number marker. Quoteexcept RAW which by definition is not s graphic format Really, what is it then..?  I'll leave you to correct the wiki entry. -> http://en.wikipedia.org/wiki/Raw_image_format ps. I'm not saying magic numbers is a bad, I use them myself, but just pointed out a potential problem with using them.  My take is if your graphics format are simple, and your sticking to the common image formats  BMP/JPG/PNG etc, then having an option might be an idea!!. ---------------------------------------------------------------------- Jose Mejuto · 2012-10-17 18:53 Hello, First, sorry about posting with different user name, the previous is an old one that was laying around in my laptop Quote from: KpjComp on October 17, 2012, 02:05:00 pmQuoteThe graphics formats are all of them selectable using the first 16 bytes So you know for sure that there is no potential of an overlap with all Image formats, & using magic numbers is 100% correct. So JPG/TIFF/GIF/PNG/PPM/PGM/PBM/PNM/WEBP/HDR/RGBE/IFF-RGFX/TGA/ILBM/IM G/PCX/ECW/IMG/SID/CD5/FITS/PGF/XCF/PSD/PSP/CGM/SVG/CDR/AI/PPT/VML/XPS etc/etc..  All these formats in no way could have magic numbers embedded within them from other formats causing a mismatch, or that every format even has a magic number marker. Yes, at least up the point that you can decide which format use to read. You can not know if it is a TIFF RLE or LZW but you know it is a TIFF. Also you only need to know how to separate the known Lazarus formats, the other ones are not relevant for TImage. Of course there are some formats in that list that I'm not aware of them. PNG: $89+'PNG' JPG: $FF $D8 $FF $E? GIF: GIF TIFF: MM $00 $2A or II $2A $00 (TIFF needs more attention) PPM/PPM/PGM/PBM/PNM/: I do not know... Only the ones that are based in XML or alike can have some trouble as some are zipped and needs to be unzipped (partially) to get data inside. QuoteQuoteexcept RAW which by definition is not s graphic format Really, what is it then..?  I'll leave you to correct the wiki entry. -> http://en.wikipedia.org/wiki/Raw_image_format I'm from the old school, and then the RAW "format" was a binary dump of memory without format, hence the RAW name, and as it is a binary dump, the first bytes could match anything. That is the RAW format from cameras, which in fact is a bad name, as it describes the content, not the container and there are a lot of RAW formats all of them not compatible with each other. Quoteps. I'm not saying magic numbers is a bad, I use them myself, but just pointed out a potential problem with using them.  My take is if your graphics format are simple, and your sticking to the common image formats  BMP/JPG/PNG etc, then having an option might be an idea!!. Currently LoadFromStream uses magics to use the right reader. ---------------------------------------------------------------------- KpjComp · 2012-10-17 19:54 QuoteAlso you only need to know how to separate the known Lazarus formats What is known?, Lazarus like Delphi has an image registration facility.  As such it can in theory handle any image format, even one you decide to invent yourself. QuoteCurrently LoadFromStream uses magics to use the right reader. What else could it use?, that's what I've already pointed out.  But if you look at the LoadFromFile, you will see it uses the Extension first, and then falls back to magic numbers.  And that's likely why currently blobs also store this information too. Code: [Select]    if Ext <> '' then       LoadFromStreamWithFileExt(Stream, Ext)     else       LoadFromStream(Stream); Anyway, I think enough has been said.  I'm sure I've made my point about magic numbers not been perfect.  Yes, and before somebody comes out and says that extension's are not perfect, that is correct, but at least the problem can be sorted by the user correcting it.  Expecting the image extensions to be correct really doesn't seem a big ask anyway. ---------------------------------------------------------------------- Jose Mejuto · 2012-10-18 13:43 Quote from: KpjComp on October 17, 2012, 09:54:12 pmQuoteAlso you only need to know how to separate the known Lazarus formats What is known?, Lazarus like Delphi has an image registration facility.  As such it can in theory handle any image format, even one you decide to invent yourself. Hello, Right. QuoteWhat else could it use?, that's what I've already pointed out. One year ago it simply does not work, and there were not available way to do it. QuoteBut if you look at the LoadFromFile, you will see it uses the Extension first, and then falls back to magic numbers.  And that's likely why currently blobs also store this information too. I know it, and I was opposed to that way, it should be the inverted if (IMHO), but as it does not limit your code as one can use the LoadFromStream directly, no problem to me. QuoteAnyway, I think enough has been said. Yes sure. I like the magic numbers detection which can be overridable using events or any other mechanism. QuoteExpecting the image extensions to be correct really doesn't seem a big ask anyway. Well, it is if you develop forensic software ---------------------------------------------------------------------- Jurassic Pork · 2013-08-05 06:01 hello, is someone interested by an example of new version of tdbimage (lazarus 1.1 svn after 1 may 2013) ? (see screenshot in attachment) In this example : - Use SqlDb components. - Sqlite3 database biolife with 5 fishes. - The images are stored in blob field without extension at the beginning.   With this you can view blob images with database browser editor (ex sqlite2009pro). - In the database there is also a field with images links (filenames). - You can see the linked images in a Timage. - The linked images are stored in the folder images of the project. - You can change the images in the database :   - for Tdbimage double click on the component and choose your image.   - for Timage click on the button near the image filename.(you must be in edit mode )     To not store the extension at the beginning of the blob an empty procedure DBImage1DBImageWrite  is used :  Code: [Select] procedure TForm1.DBImage1DBImageWrite(Sender: TObject; S: TStream;   GraphExt: string); begin end;   To detect the type of graphic when reading blob , magic number detection is used in DBImage1DBImageRead  Code: [Select] procedure TForm1.DBImage1DBImageRead(Sender: TObject; S: TStream;   var GraphExt: string);   var val1,val2:  WORD;   begin    S.Seek(0, soFromBeginning);    S.Read(val1,2);    S.Position := 2;    S.Read(val2,2);    if (val1 = $4D42) then  GraphExt := 'bmp';    if (val1 = $4947) and (val2 = $3846) then  GraphExt := 'gif';    if (val1 = $5089) and (val2 = $474E) then  GraphExt := 'png';    if (val1 = $D8FF) and (val2 = $E0FF) then  GraphExt := 'jpg';    S.Seek(0, soFromBeginning); end;    Friendly, J.P ---------------------------------------------------------------------- BigChimp · 2013-08-05 06:34 JP, sounds like a good idea for SQLDBTutorial4 on the wiki... or perhaps a page called TDBImage... If you have a working demo, I think submitting it to the bugtracker as an example for a directory $(lazarusdir)\examples\database\TDBImage\ would be very nice - Lazarus can do with some more db demos. One thing though: is your database free of any Borland/Embarcadero copyrighted material (images, text)? If not, perhaps time to write up our own fish facts... (As for the sqlite database schema: even if that doesn't fall under the copyright exception about one single possible/logical way to do things, it would fall under interoperability exceptions: by providing this demo we can use/show interoperation with Delphi examples) ---------------------------------------------------------------------- BigChimp · 2013-08-05 06:44 Oh, I'm perfectly willing to help with a wiki page/article... just don't want to start another tutorial by myself... ---------------------------------------------------------------------- Jurassic Pork · 2013-08-05 08:15 hello bigchimp, QuoteOne thing though: is your database free of any Borland/Embarcadero copyrighted material (images, text)? do you think there is problem with copyright ? 1 - THe database is a sqlite3 database not an embarcadero database  2 - Even if the contents of the database have parts of original fishfact borland demo, i don't see copyright in the pictures and the texts (borland demo)  . If Embarcadero is an    call a lawyer. ---------------------------------------------------------------------- BigChimp · 2013-08-05 08:35 Hi my porcine friend, Quote from: Jurassic Pork on August 05, 2013, 10:15:38 amdo you think there is problem with copyright ? Not necessarily as it always is very subjective and depends on jurisdictions, judge/jury mood etc. However, to avoid the possibility of the consequences in 2. happening and getting bad publicity (and even perhaps questioning the rest of the code) I suggest we use some fish of our own I'd be happy to come up with something. Quote from: Jurassic Pork on August 05, 2013, 10:15:38 am1 - THe database is a sqlite3 database not an embarcadero database  Agreed. Therefore the physical implementation of the schema is probably different than whatever Borland used (Paradox? Interbase?) which already differentiates them. Also, regardless of the above: there's only a couple of ways or perhaps "one true way" to create a properly normalized db/a good example db so it doesn't matter if the schema is quite alike. No problems there, I'd say. Quote from: Jurassic Pork on August 05, 2013, 10:15:38 am2 - Even if the contents of the database have parts of original fishfact borland demo, i don't see copyright in the pictures and the texts (borland demo)  . If Embarcadero is an    call a lawyer. Well yes, if it were my own project I might take that chance. However, there's more people watching and... well, what I said above. ---------------------------------------------------------------------- Jurassic Pork · 2013-08-06 13:49 hello, i have created a new sqlite3 Database for my project. It contains mushrooms. I haven't found jurassic mushrooms, then i have taken deadly mushrooms. All the texts and images come from wikipedia. Features: - Use SqlDb components. - Sqlite3 database DeadlyMushrooms with 5 mushrooms. - The images are stored in blob field without extension at the beginning.   With this you can view blob images with database browser editor (ex sqlite2009pro). - In the database there is also a field with images links (filenames). - You can see the linked images in a Timage. - The linked images are stored in the folder images of the project. - You can change the images in the database :   - for Tdbimage double click on the component and choose your image.   - for Timage click on the button near the image filename.(you must be in edit mode ) - Transaction commit when you click on Tdbnavigator refresh button or on close form. - Small pictures of the mushrooms are in the sqlite3Database. Largest images are in files in the folder images. In attachment a screenshot of the project.  Friendly, J.P ---------------------------------------------------------------------- BigChimp · 2014-01-10 11:37 Hi Jurassic Pork, Haven't seen any mushrooms come up in the Lazarus examples directory... Just wondering if you had a chance to upload it as an example to the bugtracker... (especially as I'm fighting a bit with dbimage myself ) Thanks, BigChimp ---------------------------------------------------------------------- Jurassic Pork · 2014-01-10 17:37 hello bigChimp, i have MushRooms database project in a 7zip file but it is too big for this forum ( 260k > 250k) where to upload it ? Friendly J.P ---------------------------------------------------------------------- BigChimp · 2014-01-10 17:42 You can attach it to a bug report in the bug tracker as a sample project for Lazarus db components. ---------------------------------------------------------------------- Jurassic Pork · 2014-01-10 17:56 mantis free pascal bugtracker issue  0025511 ---------------------------------------------------------------------- BigChimp · 2014-01-10 18:00 Great, thanks! POsted a comment there ---------------------------------------------------------------------- Jurassic Pork · 2014-01-15 02:19 Hello BigChimp, i have added a lazreport report in my Mushroom Database  and a print button to print the report with all the mushrooms in the database. In each page of the report : a title the field common_name of the mushroom database. the field notes of the mushroom database. the field picture of the mushroom database (picture picture1). the picture of the field image_link (picture picture2). the report  name is Mushroom_Report.lrf to do that : i have patched the laz_class.pas of the lazreport component with this patch new procedures in unit1.pas Code: [Select]procedure TForm1.frReport1DBImageRead(Sender: TObject; S: TStream;   var GraphExt: string); var val1,val2:  WORD; begin     S.Seek(0, soFromBeginning);    S.Read(val1,2);    S.Position := 2;    S.Read(val2,2);    if (val1 = $4D42) then  GraphExt := 'bmp';    if (val1 = $4947) and (val2 = $3846) then  GraphExt := 'gif';    if (val1 = $5089) and (val2 = $474E) then  GraphExt := 'png';    if (val1 = $D8FF) and (val2 = $E0FF) then  GraphExt := 'jpg';    S.Seek(0, soFromBeginning); end; procedure TForm1.frReport1EnterRect(Memo: TStringList; View: TfrView); begin     if View.Name = 'Picture2' then        if   DBEdit1.Text <> '' then   TFrPictureView(View).Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) +   'images' +  DirectorySeparator +  DBEdit1.Text); end;  original source of the database  with the sqlite3 Imagetest.db3 database is here the modified or added files   in attachments Friendly J.P ---------------------------------------------------------------------- Jurassic Pork · 2014-01-16 02:12 they are some errors in the project. A new archive of the project is available here you need to register to see and download attachments in this forum. here the  new readme of the project : QuoteMushRoomsDatabase by Jurassic Pork - January 2014 Features: - Use SqlDb and lazreport components. - Sqlite3 database DeadlyMushrooms with 5 mushrooms. - The images are stored in blob field without extension at the beginning. With this you can view blob images with database browser editor (ex sqlite2009pro). - In the database there is also a field with images links (filenames). - You can see the linked images in a Timage. - The linked images are stored in the folder images of the project. - You can change the images in the database : - for Tdbimage double click on the component and choose your image. - for Timage click on the button near the image filename.(you must be in edit mode ) - Transaction commit when you click on Tdbnavigator refresh button or on close form. - Small pictures of the mushrooms are in the sqlite3Database. Largest images are in files in the folder images. - Print button to print all the mushrooms (lazreport). On each page you have : a title the field common_name of the mushroom database. the field notes of the mushroom database. the field picture of the mushroom database (picture picture1). the picture of the field image_link (picture picture2). the report name is Mushroom_Report.lrf Notes : Depending of your Lazarus version, you need to patch the following files before to load and compile the project : 1 - file lazarus/lcl/dbctrls.pp and file lazarus/lcl/include/dbimage.inc add OnDBImageRead and OnDBImageWrite properties 2 - file lazarus/components/lazreport/source/lr_class.pas add OnDBImageRead property The file dbImage.patch contains the modifications in the files that may be you have to do. you need to recompile ide after patches. Friendly J.P ---------------------------------------------------------------------- BigChimp · 2014-01-16 09:04 Thanks JP, will have a look! ---------------------------------------------------------------------- BigChimp · 2014-01-17 16:06 Nice example - glad it got into the Lazarus example programs ---------------------------------------------------------------------- Jurassic Pork · 2014-01-18 00:48 finally the project is now in the lazarus svn dev repository  examples/database/sqlite_mushrooms link you must upgrade your files with the files in the repository  to have the last updated version of the project.  the patch dbimage.patch and  readme part for the patch are no longer in this version but may be necessary for the current or old versions of lazarus ---------------------------------------------------------------------- BigChimp · 2014-08-11 14:30 Firebird embedded support was added and the directory renamed from  examples/database/sqlite_mushrooms to  examples/database/image_mushrooms to better reflect current project contents/purpose. Link: http://svn.freepascal.org/svn/lazarus/trunk/examples/database/image_mu shrooms