# Paintable Canvas Repaint Performance

**URL:** <https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159>\
**Category:** Ignition\
**Tags:** ignition79, scripting\
**Created:** [October 15, 2018, 7:00pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159 "2018-10-15T19:00:35Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![WPhan](https://avatars.discourse-cdn.com/v4/letter/w/82dd89/32.png) [@WPhan](https://forum.inductiveautomation.com/u/WPhan)\
**Post date:** [October 15, 2018, 7:00pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/1 "2018-10-15T19:00:35Z")

</div>

I have been running into issues with the repaint event handler taking up too much of the client resources. This code takes the byte array into an image. Recently the images we have displaying became higher resolution. The byte array expanded from ~80,000 to ~500,000. I have taken some tips from [slower/stop repainting](http://forum.inductiveautomation.com/t/paintable-canvas-slower-stop-repainting/16384) but it is still quite slow client side, within my designer it perform well. I am not sure what I can do to improve performance.

## **Old Code**

```auto
g = event.graphics
bytes = system.file.readFileAsBytes("C:\\imagefile.PNG")
if bytes:
	from javax.imageio import ImageIO
	from java.io import ByteArrayInputStream
	image = ImageIO.read(ByteArrayInputStream(bytes))
	scaledImage = image.getScaledInstance(700,600,0)
	g.drawImage(scaledImage,0,-15,event.source)

```

* * *

## **New Code**

**_Repaint_**

```auto
g = event.graphics
filename = "C:\\imagefile.PNG"
image = event.source.getClientProperty("img-cached")

if not event.source.manualTextFieldModified and image:
	g.drawImage(image, 0, 0, 820, 615, event.source)

```

**_propertyChange_**

```auto
filename = "C:\\imagefile.PNG"

image = event.source.getClientProperty("img-bytes-cached")

if event.source.manualTextFieldModified or not image:
	from javax.imageio import ImageIO
	from java.io import ByteArrayInputStream
	bytes = system.file.readFileAsBytes(filename)
	image = ImageIO.read(ByteArrayInputStream(bytes))
	event.source.putClientProperty("img-cached",image)
	system.tag.write("manualTextFieldModified", 0)

```

---

<div class="post-metadata">

**Author:** ![mrogers](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mrogers/32/4110_2.png) [@mrogers](https://forum.inductiveautomation.com/u/mrogers)\
**Post date:** [October 15, 2018, 7:15pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/2 "2018-10-15T19:15:36Z")

</div>

Hmm. New code looks good overall to me. One note though, please use the preformatted text option (it looks like a laptop in the toolbar above the comment, or press ctrl+shift+C. Its much easier to read.)

I’m wondering why you’re using a paintable canvas for this, though. This looks like a job for the normal image component, uhnless you’re doing more with it. The image filename looks static, perfect for the image component. If not, I believe theres a way to dynamically edit the images in the little image browser that pops up when you select an image. Unfortunately I’m not familiar with that, but hopefully someone else can point out how to do that, if its possible.

---

<div class="post-metadata">

**Author:** ![WPhan](https://avatars.discourse-cdn.com/v4/letter/w/82dd89/32.png) [@WPhan](https://forum.inductiveautomation.com/u/WPhan)\
**Post date:** [October 15, 2018, 7:29pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/3 "2018-10-15T19:29:43Z")

</div>

Sorry about that, I didn’t realize they have preformatted text.

I am using a path that isn’t reachable with the client. It is located on the host gateway computer.

---

<div class="post-metadata">

**Author:** ![mrogers](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mrogers/32/4110_2.png) [@mrogers](https://forum.inductiveautomation.com/u/mrogers)\
**Post date:** [October 15, 2018, 7:47pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/4 "2018-10-15T19:47:10Z")

</div>

Try setPath() on the image component (see [here](http://files.inductiveautomation.com/sdk/javadoc/ignition79/794-beta1/index.html?com/inductiveautomation/ignition/gateway/model/GatewayContext.html)). But I was rereading your code, your propertyChange script - does it check for event.propertyName? If not, that’s probably the issue.

---

<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:** [October 15, 2018, 7:48pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/5 "2018-10-15T19:48:29Z")

</div>

Unfortunately, there’s an upper bound to Java Swing’s graphic performance - all operations are CPU-bound, rather than using the GPU for painting related tasks. A large byte array is always going to be “expensive” to draw. You can _try_ enabling hardware acceleration using a command line flag, but your results may vary - this option is disabled by default and not something we test against:  
[`-Dsun.java2d.opengl=true`](https://docs.oracle.com/javase/10/troubleshoot/java-2d-pipeline-rendering-and-properties.htm#JSTGD439) (see the [manual](https://docs.inductiveautomation.com/display/DOC79/Native+Client+Launchers#NativeClientLaunchers-CustomLaunchSettings) for instructions on how to use command line flags)

---

<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:** [October 15, 2018, 7:54pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/6 "2018-10-15T19:54:59Z")

</div>

Also, I don’t know if you just omitted this for copy-pasting, but if your `propertyChange` script is exactly what you posted, then you can also get an easy performance gain by only actually running your code if the event is relevant, ie:

```auto
if event.propertyName == 'manualTextFieldModified':
    # put the rest of your code here

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 15, 2018, 8:02pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/7 "2018-10-15T20:02:50Z")

</div>

> [@paul-griffith](#):
>
> you can also get an easy performance gain by only actually running your code if the event is relevant

There are so many reasons a propertyChange event can be fired that I consider it a bug if the propertyName is not checked.

---

<div class="post-metadata">

**Author:** ![WPhan](https://avatars.discourse-cdn.com/v4/letter/w/82dd89/32.png) [@WPhan](https://forum.inductiveautomation.com/u/WPhan)\
**Post date:** [October 15, 2018, 8:18pm UTC](https://forum.inductiveautomation.com/t/paintable-canvas-repaint-performance/20159/8 "2018-10-15T20:18:12Z")

</div>

I did not notice any performance gain from this code change.

> [@paul-griffith](#):
>
> if event.propertyName == 'manualTextFieldModified':  
> # put the rest of your code here

The whole reason I embarked on improving the code was that when I used the old code. It would bog down all the text fields and drop downs. The text fields values are used within the image itself. The new code does not bog down the client but it takes way a while to load.

Transition Time between the new different image sizes.

**Old Code**  
Small Image -\> Big Image = Load time 8 secs  
Large Image loaded modify text on image = 6 secs  
Big Image to Small Image = 6 secs  
Down side, everything is slower.

**New Code**  
Small Image -\> Big Image = Load time 22 secs  
Large Image loaded modify text on image = 4 secs  
Big Image to Small Image = 4 secs
