Image Explorer

Discussion in 'Share Your Creations' started by dlfallen, May 1, 2007.

  1. dlfallen

    dlfallen Active Member Licensed User


    Erel has mentioned several times that the BinaryFile.dll can be used to store bitmap images. Using them, however, takes a little doing. You can randomly access any image with this code (assume your object is named Img):
    Img.position = Pos
    Where Pos is the position of the image in the data file -- 78848 for example, and Image1 is the control that the image is being read to (it could also be an image button, an ImageList, or any control that takes an image). The problem is knowing the correct value of Pos for any given image.

    Image Explorer is a tool for reading an image library created using BinaryFile, and give various pieces of information -- see the screen shot. When run, the program begins by asking you to pick the image file to be opened. Make sure you put the sample image file (Images.dat) in a directory accessible by your PPC.

    Image Explorer does refuse to read past the end of the binary file so as to avoid crashing, but does not check on whether the file loaded is a valid BinaryFile.dll - generated file. Trying to run Image Explorer against any other type of input will probably cause a crash so be careful.

    (1) Is there a way to tell if the file being opened is a legitimate image file? I suppose I could read the first few bytes and look for "BM" but I thought maybe you would have a better way.
    (2) I detect which image is the last by comparing the file size to the position after loading the image. The first image file I tested the position was exactly the same as the file size. The second image file was 8 bytes shorter than the file size. The program above compares the file size to the last position + 32. Is this a reliable method, or is there a better way?

  2. Erel

    Erel Administrator Staff Member Licensed User

    Looks great, but I don't see the attachment :signOops:
    1) You can use the ErrorLabel to catch the error if the file is not an image file.
    2) EmbedFile writes the file length (8 bytes) and then it writes the complete file to the target file.
    Usually you don't need to know the file position as you are reading all the files in sequence (the same order as you wrote the files).
    You've got 32 bytes because there were 4 files embedded, but if there were more then the number will be different.
  3. dlfallen

    dlfallen Active Member Licensed User

    I don't know why the attatchment isn't there. I uploaded the file and got a message saying the upload was successful. I'll try attatching it to THIS post.

    Yes, you do not need to know file positions when reading sequentially. But there are situations where you might want to read a particular image in a collection. That can be done directly if you know the file position. In my cards.dat file, when I want to display the King of Spades I don't want to have to read in the previous 51 cards first.

    I apparently did not clearly explain the end of file problem. In the example file (Images.dat) there are 5 (not 4) embedded files. After reading the last bitmap, the value returned by "Img.position" is 206752. When I originally open Images.Dat the command "FileSize("Images.Dat") returns 206752. These two values are equal so my first attempt at detecting the end of file was to compare these two values and quit if they were equal.

    I have a second image file I tested the program on. This file, cards.dat, has 63 images. FileSize("Cards.dat") returns a length of 397834. However, after reading in the last image, Cards.position returns 397826 which is 8 bytes less than the file size. So I modified the app to quit if the final position plus 32 was greater than the file size. I'm guessing it is a DWORD boundary problem and final position plus 8 would have been good enough, but 32 should be safe.

    Finally, unless I'm missing something here ErrorLabel doesn't help. The problem is the program can go off in to never-never land when Img.RetrieveImage is executed on a file that is not an image file created by BinaryFile.dll. Error trapping does not help in this instance.
  4. Erel

    Erel Administrator Staff Member Licensed User

    I agree with you that there are cases when it is better to "pull" a specifc image from file. However for a card game you could load all the images to an ImageList and then use ImageList.Item to retreive the specific image.

    You could use BinaryFile.ReadInt64 and see if the value is a positive (not too big) number. Afterwards you will need to return the file position 8 bytes backwards.
  5. dlfallen

    dlfallen Active Member Licensed User

    Good point about using ImageList -- it has an added advantage in my card game application. I spent some time getting each bitmap to have exactly the same file size so I could calculate any given file's start position. Using the ImageList approach I could have used files of different sizes with no problem.

    I've tested the binaryfile and have verified it can read the following image formats: BMP, JPG, GIF, TIF, PNG, DIB, and TIF (both). I have added code to test for the signature for each of these file types. That works well, but I wonder if there are any other file formats I have missed?

  6. Erel

    Erel Administrator Staff Member Licensed User

    This is the complete list.
  7. dlfallen

    dlfallen Active Member Licensed User

    OK, I added code to detect what type of image was being read. To test this, I added sample images in BMP, JPG, TIF, PNG, and GIF formats (your previous post said these formats were supported). The program runs flawlessly on the PC but does not run on the PPC. Through trial and error I have determined that the PPC will read BMP, JPG, PNG, and GIF files but not TIF files. Attempting to read a TIF file returns an "ArgumentExecption" error when RetrieveImage is executed.

    Is the binaryfile.dll supposed to support retrieving TIF images? I assume it is because TIF images can be retrieved on the desktop PC.
  8. Erel

    Erel Administrator Staff Member Licensed User

    No. The BinaryFile will not help here.
  9. dlfallen

    dlfallen Active Member Licensed User

    OK, I thought TIF files were supported, but I guess not. Perhaps you could annotate your help files to indicate that binaryform.dll can be used to store and retrieve images in BMP, JPG, PNG, and GIF formats but not in other bitmap formats such as TIF, ICO, CUR, or PCX.

  10. dlfallen

    dlfallen Active Member Licensed User

    Final Version

    Attached is the final version of Image Explorer, a tool for browsing image files created with binaryfile.dll.

    It now supports BMP, GIF, PNG, and JPG files. It gives basic information about the image files and will not attempt to retrieve an image unless the file header indicates a compatible image.

  11. Erel

    Erel Administrator Staff Member Licensed User

  12. mijail

    mijail New Member

    Hi, I am new

    Is there any way to extract icon image of an .exe or .dll file. In windows use the API Shell32 but in basic4ppc how it is posible.

  13. alfcen

    alfcen Well-Known Member Licensed User

    Hello David,

    Very handy tool !

    Please allow me a recommendation that will shorten your code.
    Instead of the Sub ParseFileName, you could simply code

    Form1.Text = StrToLower(FileName(OpenDialog1.File))

    I am not sure about TIFFs, but they should not be LZW or otherwise compressed.