Images folder location in containerized Vision 8.1 for rendering disk image

When running in a containerized version of Ignition 8.1, does anyone know where I can find the images folder absolute path that I can access with the Vision Images widget?

I need to transfer things into a tmp folder there so I can show them in client, but I can not find the absolute path inside of the designer (right click copy path gets only the relative path…), so while I recursively scrape all of the filestructure and look for it I thought I’d ask here.

Currently scraping my /usr/local/bin/ignition/ folder, but I don’t have awesome tooling for that so its akin to shooting in the dark.

In 8.1 (and all prior Ignition versions) images in 'Image Management' are stored inside the internal database; for most of the recent past that means a SQLite file, config.idb, on disk.
While machine extraction is possible, you should not do it at runtime.

If you just want to dump all the images out of a GWBK (easily), you can use Kindling to do so with a nicer graphical interface.

Or you can do it yourself using SQLite - the table is literally IMAGES:

(In 8.3 this is all moot, as images are actually stored on disk, though still within the 'resource' storage format we use inside Ignition, so there's extra metadata 'attached' to files besides just the image file).

1 Like

Ah thank you for this – I was on a wild goose chase looking for the folder! I’m mostly looking to insert into that table rather than pull from it, but I might be able to do that with this information. Is it safe to modify this file during runtime?

Basically, I want to pull up images that are created through actions users might take in our HMI, and they are on a network drive. That drive is accessible to Ignition, but the Image widget doesn’t seem to be able to load the images so I was going to make temp copies into where the image widget could load them. Maybe there is a way to modify the image widget to load from the mounted drive directly instead?

Not externally. With a gateway script accessing the Persistence Interface, yes. (Totally unsupported, and not used in v8.3.)

The supported technique would be to use WebDev to expose the gateway-accessible files as URLs that the image component can use.

(You can also ditch the Image component and use a Paintable Canvas to display images retrieved via system.util.sendRequest(). WebDev not required for that.)

2 Likes

Thank you this was the hint I needed!

I made a gateway event script that to loads the image into bytes:

def handleMessage(payload):
    path = payload.get("path")
    if not path:
        return None
    
    from java.nio.file import Files, Paths
    p = Paths.get(path)
    return Files.readAllBytes(p)   # returns byte[]

then I access it with a script hook like

def show_image(event):
    from java.io import ByteArrayInputStream
    from javax.imageio import ImageIO
    
    b = system.util.sendRequest(project="base_leaf",
                                messageHandler="get_image_bytes",
                                payload={"path": system.tag.readBlocking(["[PROV]path_thumbnail"])[0].value},
                                timeout=5000)
    # b is typically a Java byte[] or Python sequence of bytes
    img = ImageIO.read(ByteArrayInputStream(b))
    canvas = event.source.parent.getComponent('Paintable Canvas')
    canvas.putClientProperty("img", img)   # img is a BufferedImage from ImageIO.read(...)
    canvas.repaint()

I have this code in the paintable canvas:

def foo(event):
    g = event.graphics
    img = event.source.getClientProperty("img")
    if img is None:
        return
    
    from java.awt import RenderingHints
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    
    iw = img.getWidth(None)
    ih = img.getHeight(None)
    if iw <= 0 or ih <= 0:
        return
    
    cw = event.width
    ch = event.height
    
    sx = float(cw) / float(iw)
    sy = float(ch) / float(ih)
    s = sx if sx < sy else sy
    
    dw = int(iw * s)
    dh = int(ih * s)
    dx = int((cw - dw) / 2)
    dy = int((ch - dh) / 2)
    
    g.drawImage(img, dx, dy, dw, dh, None)
    
foo(event)

It seems to work! Code for reference in case anyone else tries to do this later

1 Like

If you're specifically trying to use images hosted in image management there's no need for a gateway message handler or a paintable canvas. Just make the source URL a concatenation of the gateway hostname/port combo, /system/images/, and the path of your image. Images in image management are automatically publicly accessible over the network (even on 8.1/7.9).

He was trying to get images into image management programmatically, just to use that image component shortcut. But really wants to display images from the gateway filesystem.

1 Like

"I was elected to lead, not to read"

Carry on then :smiley:

3 Likes

No worries. I've had a bad week for reading comprehension myself. :grimacing: