# Image Management Tool

**URL:** <https://forum.inductiveautomation.com/t/image-management-tool/37558>\
**Category:** Ignition\
**Created:** [August 10, 2020, 3:40pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558 "2020-08-10T15:40:28Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 10, 2020, 3:40pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/1 "2020-08-10T15:40:28Z")

</div>

Does anyone have an example of using the Image Management Tool to upload images from a client? Currently using version 7.9. I found the post below, but have not been even close to successful in getting it to work.

[[Image Management Tool Query](http://forum.inductiveautomation.com/t/image-management-tool-query/32652)]

Thanks!

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 10, 2020, 6:45pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/2 "2020-08-10T18:45:34Z")

</div>

```auto
from java.awt import Toolkit
from java.io import File
from org.apache.commons.io import FilenameUtils
from com.inductiveautomation.ignition.designer.gateway import DTGatewayInterface

gi = DTGatewayInterface.instance
filepath = system.file.openFile()
if filepath is not None:
	name = File(filepath).name
	javaImage = Toolkit.defaultToolkit.getImage(filepath)

	gi.uploadImage(event.source, name, "Script uploaded image", FilenameUtils.getExtension(filepath), "", javaImage.width, javaImage.height, system.file.readFileAsBytes(filepath))

```

Something like this might do it.

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 10, 2020, 7:53pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/4 "2020-08-10T19:53:28Z")

</div>

very close, after a couple minor mods, I am getting TypeError: uploadImage(): expected 9 args; got 8

```auto
from java.awt import Toolkit
from java.io import File
from org.apache.commons.io import FilenameUtils
from com.inductiveautomation.ignition.designer.gateway import DTGatewayInterface

# gi = DTGatewayInterface.instance
gi = DTGatewayInterface

filepath = system.file.openFile()

if filepath is not None:

	name = File(filepath).name

#	javaImage = Toolkit.defaultToolkit.getImage(filepath)
	javaImage = Toolkit.getDefaultToolkit().getImage(filepath)

	gi.uploadImage(event.source, name, "Script uploaded image", FilenameUtils.getExtension(filepath), "", javaImage.width, javaImage.height, system.file.readFileAsBytes(filepath))

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 10, 2020, 8:46pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/5 "2020-08-10T20:46:36Z")

</div>

Any stack trace on the TypeError? The call you’re using lines up with the signature I’m expecting. What Ignition version?

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 10, 2020, 9:49pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/6 "2020-08-10T21:49:28Z")

</div>

Version 7.9.13

```auto
Traceback (most recent call last):
  File "<event:actionPerformed>", line 18, in <module>
TypeError: uploadImage(): expected 9 args; got 8

	at org.python.core.Py.TypeError(Py.java:235)
	at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:209)
	at org.python.core.PyReflectedFunction.throwArgCountError(PyReflectedFunction.java:262)
	at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:319)
	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:167)
	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:204)
	at org.python.core.PyObject. __call__ (PyObject.java:357)
	at org.python.core.PyObject. __call__ (PyObject.java:361)
	at org.python.pycode._pyx4.f$0(<event:actionPerformed>:18)
	at org.python.pycode._pyx4.call_function(<event:actionPerformed>)
	at org.python.core.PyTableCode.call(PyTableCode.java:165)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1275)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:636)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:180)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:271)
	at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
	at com.sun.proxy.$Proxy35.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue.access$500(Unknown Source)
	at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Ignition v7.9.13 (b2019120915)
Java: Azul Systems, Inc. 9.0.7.4

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 10, 2020, 11:12pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/7 "2020-08-10T23:12:19Z")

</div>

```auto
# gi = DTGatewayInterface.instance
gi = DTGatewayInterface

```

That changes the semantics. `uploadImage()` is an instance method on the DTGatewayInterface class - but you’re calling it as `DTGatewayInterface.uploadImage()` - which is technically allowed in Python, but only if you provide an instance of `self`, which you don’t have in this case.  
Change that line to:  
`gi = DTGatewayInterface.getInstance()`.

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 10, 2020, 11:22pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/8 "2020-08-10T23:22:19Z")

</div>

That fixed it…

I am working on a windows computer, tried to upload a file with extension “jpg” and it failed. Hardcoded “JPEG” instead of FilenameUtils.getExtension(filepath) and it worked.

Thanks.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 10, 2020, 11:33pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/9 "2020-08-10T23:33:56Z")

</div>

Ah, yeah, there’s constants on the gateway that are matched against. In 7.9 the only valid formats are:

```nohighlight
PNG
JPEG
GIF
BMP

```

You’ll have trouble with the code I posted with .bmp, I think - the width/height code won’t work, I’m pretty sure.

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 10, 2020, 11:41pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/10 "2020-08-10T23:41:16Z")

</div>

You got me over a big hump…

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 20, 2020, 5:25pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/11 "2020-08-20T17:25:15Z")

</div>

With your assistance, I got it working great in the designer, but it fails when run from a client.

Error message is

```auto
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
  File "<event:actionPerformed>", line 4, in <module>
ImportError: No module named designer

```

Following is the script, line 4 imports DTGatewayInterface:

```auto
from java.awt import Toolkit
from java.io import File
from org.apache.commons.io import FilenameUtils
from com.inductiveautomation.ignition.designer.gateway import DTGatewayInterface
#from com.inductiveautomation.ignition.client.gateway_interface import DTGatewayInterface
import imghdr

gi = DTGatewayInterface.getInstance()

filepath = event.source.parent.getComponent('File Explorer').selectedPath
image_name = File(filepath).name

image_data = system.file.readFileAsBytes(filepath)

javaImage = Toolkit.getDefaultToolkit().getImage(filepath)

#valid image types PNG, JPEG, GIF, BMP
image_type = imghdr.what(str(filepath)).upper()

folder = "%s/" % event.source.parent.sop_id

images = gi.getImageList(event.source, folder)
new_image = True
for i in range(images.rowCount):
	if '%s%s' % (folder,image_name) == images.getValueAt(i, 'path'):
		new_image = False
		break

if new_image or system.gui.confirm('Image %s already exists for this SOP. Overwrite?' % image_name, 'Image Exists'):

	gi.uploadImage(event.source, image_name, "Image Description", image_type, folder, javaImage.width, javaImage.height, image_data)
	project.procedure.item_add(system.gui.getWindow('sop_edit').getRootContainer().getComponent('procedure'), event.source.parent.index, 20400, event.source.parent.level, '%s%s' % (folder,image_name))
	system.nav.closeParentWindow(event)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 20, 2020, 9:21pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/12 "2020-08-20T21:21:57Z")

</div>

DTGatewayInterface only exists in the designer. Technically you could try sending a message over our interface from a client, but I'm not positive it'll be allowed from the client scope...

A perhaps better option that would work on both scopes would be a gateway level function in a message handler - look around this forum for IgnitionGateway/SRContext, then call `getImageManager()`, from which you can call the uploadImage method directly with basically the same arguments you were already supplying:

```auto
public void insertImage(String name, String desc, ImageFormat type, final String dir, byte[] input, int width, int height, int size) {

```

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 20, 2020, 9:35pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/13 "2020-08-20T21:35:25Z")

</div>

I do not understand your response “DTGatewayInterface only exists in the client”. The script is attached to a button press. In the designer, the button press works fine. It does not work when pressed from a client. Any chance I can speak to someone about this?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 20, 2020, 11:46pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/14 "2020-08-20T23:46:00Z")

</div>

Support really isn’t equipped to deal with low level hacking like this. In case I didn’t make it clear enough - this isn’t a “supported” feature. You can technically make it work, using techniques I’ve described, but you’re entirely on your own if it doesn’t work.

`DTGatewayInterface` is a Java class that literally doesn’t exist when you’re in a client. It’s not part of the required collection of Java code to run a Vision client, so it’s not available.

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 20, 2020, 11:46pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/15 "2020-08-20T23:46:46Z")

</div>

Ok, I’m very close again…

I am passing all the parameters to a Gateway Message Handler, it is blowing up because I am putting the string ‘JPEG’ in the 3rd parameter which wants an ImageFormat. Can you tell me how to convert from the string to an ImageFormat, including any using or import. Thanks!

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 20, 2020, 11:47pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/16 "2020-08-20T23:47:25Z")

</div>

Got it.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 20, 2020, 11:48pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/17 "2020-08-20T23:48:05Z")

</div>

First,

```auto
from com.inductiveautomation.ignition.gateway.images import ImageFormat

```

Then use: `ImageFormat.JPEG` (exactly like that - no quotes, etc) as the third parameter.

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 20, 2020, 11:49pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/18 "2020-08-20T23:49:59Z")

</div>

You cannot believe how many variations of that I attempted. I’ll post the full solution after I clean it up.

---

<div class="post-metadata">

**Author:** ![mcgheeiv](https://avatars.discourse-cdn.com/v4/letter/m/71c47a/32.png) [@mcgheeiv](https://forum.inductiveautomation.com/u/mcgheeiv)\
**Post date:** [August 22, 2020, 9:23pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/19 "2020-08-22T21:23:58Z")

</div>

The following works in versin 7.9.13, but any suggestions for improvement are greatly appreciated:

Gateway Event Script \ Message named image\_upload:

```auto
	from com.inductiveautomation.ignition.gateway import SRContext
	from com.inductiveautomation.ignition.gateway.images import ImageFormat
	
	context = SRContext.get()
	image = context.getImageManager()

#	1 Valid image types PNG, JPEG, GIF, BMP
	image_type = {
		'PNG' : ImageFormat.PNG,
		'JPG' : ImageFormat.JPEG,
		'JPEG': ImageFormat.JPEG,
		'GIF' : ImageFormat.GIF,
		'BMP' : ImageFormat.BMP}[payload['image_type']]

	image.insertImage(payload['image_name'], payload['image_desc'], image_type, payload['folder'], payload['image_data'], payload['width'], payload['height'], payload['size'])
	
	return

```

Script on the “Upload” button on the Vision Window:

```auto
from java.awt import Toolkit
from java.io import File
from org.apache.commons.io import FilenameUtils
import imghdr

filepath = event.source.parent.getComponent('File Explorer').selectedPath

payload = {}
payload['image_name'] = File(filepath).name
payload['image_desc'] = None

# Valid image types PNG, JPEG, GIF, BMP, fix this in the message handler
payload['image_type'] = imghdr.what(str(filepath)).upper()

# Foward slash is necessary part of folder name
payload['folder'] = "folder/"

javaImage = Toolkit.getDefaultToolkit().getImage(filepath)
payload['width'] = javaImage.width
payload['height'] = javaImage.height

size = File(filepath).length()
payload['size'] = size

payload['image_data'] = system.file.readFileAsBytes(filepath)

# Call the gateway event script message handler, named image_upload on this project
proj = system.tag.read("[System]Client/System/ProjectName").value
status = system.util.sendRequest(proj, 'image_upload', payload)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 24, 2020, 3:22pm UTC](https://forum.inductiveautomation.com/t/image-management-tool/37558/20 "2020-08-24T15:22:18Z")

</div>

The imageformat stuff could be simplified a little bit:

```auto
	image_type = ImageFormat.valueOf(payload["image_type"].upper())

```

Java enum classes automatically get a `valueOf` method that does a case sensitive string comparison and throws an exception if the value is not found.
