Image Explorer

dlfallen

Active Member
Licensed User
Longtime User
ImageExp.JPG


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
Image1.Image=Img.RetrieveImage
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.

EREL:
(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?

dlfallen
 

Erel

B4X founder
Staff member
Licensed User
Longtime 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.
 

dlfallen

Active Member
Licensed User
Longtime 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.
 

Erel

B4X founder
Staff member
Licensed User
Longtime 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.
 

dlfallen

Active Member
Licensed User
Longtime 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?

dlfallen
 

dlfallen

Active Member
Licensed User
Longtime 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.
 

dlfallen

Active Member
Licensed User
Longtime 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.

-dlfallen
 

dlfallen

Active Member
Licensed User
Longtime User
Final Version

ImageExp.jpg

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.

-dlfallen
 

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.

Thaks
 

alfcen

Well-Known Member
Licensed User
Longtime 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.

Cheers
Robert
 
Top