Image control - not loading/showing?

I have a standard ABC screen and standard Image Control on it. The image link is stored in the database field.

?Image1{prop:text} = clip(PHO:ImageLink)

It works fine when an image file is located somewhere in the local driver BUT sometimes the image not showing if it is located on the net driver (UNC name) or it takes a while to load.

So how I can be sure that image is loaded and only then show it??

1 Like

I’m not sure.

I was going to suggest subclassing the control and hoping to find some WM_ event that you can use to confirm it’s loaded

Then it occurred to me that you could set ?Image1{PROP:NoWidth}=TRUE
and then periodically check ?Image1{PROP:Width}

If the IMAGE control already has another image loaded, I’m not sure you’ll achieve the desired result with that solution.

1 Like

Thank you, Mark. Will try to think about it.

But it looks like over-killing that standard functionality.

Maybe load file content to local variable and then assign it to ?Image{Prop:ImageBits} would be faster?

2 Likes

Have you tried Exists(Filename)?

I know I could used UNC \Network\Shares\SomeFolder\someFile.ext as the path for tps files, but dont know if Exists(Filename) works.

EXISTS (return file or folder existence) 
An expression containing the DOS filename.
The EXISTS procedure returns true (1) if the file is available on disk. If the file is not available, EXISTS returns false (0). You can also use EXISTS to check for the existence of any folder.

Thing is, if Clarion’s Exists(file) is this Windows api, then its got caveats, namely it can detect the UNC file but not UNC folders so it should work for your image file detection.
PathFileExistsA function (shlwapi.h) - Win32 apps | Microsoft Docs

Remarks

This function tests the validity of the path.

A path specified by Universal Naming Convention (UNC) is limited to a file only; that is, \server\share\file is permitted. A UNC path to a server or server share is not permitted; that is, \server or \server\share. This function returns FALSE if a mounted remote drive is out of service.

Now the reason for not detecting network shares is that you can have a network defined on a workstation and not connect to it because you might not have permission, but this would be some of API I would use to test if a UNC share existed.

WNetOpenEnumA function (winnetwk.h) - Win32 apps | Microsoft Docs
WNetEnumResourceA function (winnetwk.h) - Win32 apps | Microsoft Docs
NetShareEnum function (lmshare.h) - Win32 apps | Microsoft Docs

Edit: Having reread what you put, it sounds like you are getting throttled by the network, so maybe you could use Exists() to detect its not locally stored and then pull it over the network to a local temp folder before displaying it? And whilst you are copying the file over the network display a temp image saying "downloading image "or “fetching image”

I would this API to get feedback on the progress of the network share copy, its a callback procedure
CopyFileExA function (winbase.h) - Win32 apps | Microsoft Docs
I idont know what security access rights restrictions you might experience using this call back function. I know I’ve experienced some access rights issues with some callback procedure but I cant see any mentioned on this api so you probably wont have any problems.

Are they big image files or a slow network/internet connection?

FWIW.

For sure image file exists (user selects it using FileDialogue).

Probably both, but it works from other applications, for example, from the iPad. Sounds and looks strange, like Clarion stucks loading image sometimes…

It did exist at the time the user selected it, but thats all you can say!

These are the other factors to contend with
Path notation being used? eg UNC or Mapped Drives?
Windows version. Offline file cache from Pro onwards
File types? eg jpg, png, bmp

We dont even know what API’s Clarion is using to display images, so yeah.

1 Like

How about, instead of loading the image directly from the UNC share, first copy the image to the local disk using the copy command from Clarion (a temp folder inside the application folder), then load the image to the ?Image1{prop:text} = clip(PHO:ImageLink)

If changes are made, copy the image back to the UNC share or discard the temporary image if no changes

Another thing to consider could be the size of the images. If the images are large, there’s the network lag plus Clarion trying to scale the image to fit in the IMAGE control. When the image is scaled down to fit in the IMAGE control, it can look bad too.
If this is the case, maybe consider accompanying the image with a scaled down version for efficient viewing. Then, if they need more detail, open the original.
ImageEx has a decent thumbnail creation facility, and its viewer is better than a plain IMAGE control.

I had a similar issue. I found that if files selected had certain charictors in the path/ name, the file would not load. I had to scan the file name variable and sort issues. I would suggest posting the long full file name inc the path of a file that works and a file that does not.

I experienced this with images larger than 72dpi.
Using 180dpi is very slow, much slower when using 300 dpi.

Difficult to say without knowing file sizes and machine specs involved.

Using Image Encoders and Decoders - Win32 apps | Microsoft Docs

Windows GDI+ provides the Image class and the Bitmap class for storing images in memory and manipulating images in memory. GDI+ writes images to disk files with the help of image encoders and loads images from disk files with the help of image decoders. An encoder translates the data in an Image or Bitmap object into a designated disk file format. A decoder translates the data in a disk file to the format required by the Image and Bitmap objects. GDI+ has built-in encoders and decoders that support the following file types:

  • BMP
  • GIF
  • JPEG
  • PNG
  • TIFF

GDI+ also has built-in decoders that support the following file types:

  • WMF
  • EMF
  • ICON

Using Images, Bitmaps, and Metafiles - Win32 apps | Microsoft Docs

Windows GDI+ provides the Image class for working with raster images (bitmaps) and vector images (metafiles). The Bitmap class and the Metafile class both inherit from the Image class. The Bitmap class expands on the capabilities of the Image class by providing additional methods for loading, saving, and manipulating raster images. The Metafile class expands on the capabilities of the Image class by providing additional methods for recording and examining vector images.

I dont know how this compares speed-wise to Larry Sands Clarion wrapper of FreeImage. FreeImage appears to be cross platform so maybe the devs have implemented their own code optimisation.

I know Lee White said he was doing a lot of peeking and poking with the metafiles for his AFE, but high dpi’s will certainly tax slow corporate desktops.

1 Like

Thank you all!

The problem is the image format. All images in my pictures samples folder have JPG extension but in reality, some of them are JPG, some PNG!

It looks like Clarion trying to show the image according to their extension and since the extension is wrong it shows nothing.

If I rename it, for example, TRAYALUR91G.jpg to TRAYALUR91G.png , then it will be shown correctly… even using UNC…

So now my question is: are there any settings to tell clarion just to show an image regardless of its extension?

You want to look at what some call Magic Bytes or Magic Numbers.

The first few bytes of a file contains pertinent information that can identify the file when the file extension is missing. This is how file recovery apps work, they scan the hard drive sometimes ignoring the FAT and recover the contiguous files from sectors starting with the known Magic Numbers.

List of file signatures - Wikipedia

Most JPG’s start off with FF D8 FF
PNG 89 50 4E 47 0D 0A 1A 0A
Gif 47 49 46 38
Bmp 42 4D

etc etc

1 Like

The next thing you’ll probably be after is a way to open the files to scan for the bytes.

Either Bruce’s StringTheory will make it easy to open the files and scan the first few bytes or you could use the windows api’s

Opening a File for Reading or Writing - Win32 apps | Microsoft Docs

The following example uses CreateFile to open an existing file for reading and ReadFile to read up to 80 characters synchronously from the file.

In this case, CreateFile succeeds only if the specified file already exists in the current directory. A subsequent call to open this file with CreateFile will succeed if the call uses the same access and sharing modes.

You’ll also need to be aware of this when trying to open files.

File Security and Access Rights - Win32 apps | Microsoft Docs

Because files are securable objects, access to them is regulated by the access-control model that governs access to all other securable objects in Windows. For a detailed explanation of this model, see Access Control.

You can specify a security descriptor for a file or directory when you call the CreateFile , CreateDirectory , or CreateDirectoryEx function. If you specify NULL for the lpSecurityAttributes parameter, the file or directory gets a default security descriptor. The access control lists (ACL) in the default security descriptor for a file or directory are inherited from its parent directory. Note that a default security descriptor is assigned only when a file or directory is newly created, and not when it is renamed or moved.

To retrieve the security descriptor of a file or directory object, call the GetNamedSecurityInfo or GetSecurityInfo function.

In this screen shot, you can see what sort of security stuff you might need to handle if you app does not have access to all files for scanning.

Use {Prop:ImageBits}, like this:

df                                  TDiskFile
sImageBytes                         &STRING
  CODE
  sImageBytes &= df.LoadFile(pImageFile)
  ImageFeq{Prop:ImageBits} = sImageBytes
  DISPOSE(sImageBytes)
1 Like

@Mike_Duglas

Yes, it works as you suggested. But using StringTheory

st.Loadfile(PHO:ImageLink) 
?Image1{Prop:ImageBits} = st:value