Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic image - works fine. Is there a way to make the rendering faster somehow? It's not a huge issue though, so this is mostly just feedback #6

Open
rubyFeedback opened this issue Nov 24, 2021 · 1 comment

Comments

@rubyFeedback
Copy link

rubyFeedback commented Nov 24, 2021

Hey there Andy,

I just tested the display of an image, based on the plenty
examples you offer.

I managed to get this to work on the first run \o/

Image screenshot:

https://i.imgur.com/xyVUCFQ.png

(Yes, this is unfinished; I just copy/pasted form.rb
and modified it ... I just wanted to see whether I can
get it to work and I can, which is good! I am a noob
tester; if I can get it to work others can as
well. :D)

Anyway I'll continue with this, but there is one thing
I noticed that is ... hmm, not a problem, but perhaps
not perfect either.

You mentioned that in the comments, that this is slow.
And indeed, on a re-draw, it takes a few seconds before
it is re-rendered.

The testing code I used was something along those
lines:

this_image = '/home/x/programming/ruby/src/backup_paradise/lib/backup_paradise/images/BACKUP_IMAGE.png'
area {
  on_draw { |area_draw_params|
    image(this_image, 96, 96)
  }
}

So, not sure if it can be made faster. But if you
have some idea, perhaps you could either add an
example or show how to fast-render an image if that
is possible. It works for my use cases already (I
only need a simple image to give a visual cue to
the elderly person on windows ... I have not tested
it on windows yet but will do so later, or tomorrow.
First I have to finish the rest) - but of course
nobody minds more speed.

I had a look at basic_image5.rb too

https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/examples/basic_image5.rb

and it uses ChunkyPNG which I suppose I could use as
well. But right now I don't know whether this approach
my be faster. If it is then perhaps I would use it,
but as I don't know right now I just stick to area {}
and image().

Perhaps at a later time I may look at basic_table_image.rb
and use a table-layout instead anyway. But right now
I just keep it simple: a single image.

If there are faster alternatives then this would be great
of course, but for my use case it suffices as-is. I can
designate the initial window size as-is via window()
so that's not a problem; resizing doesn't need to be
done. I can just add a link from the desktop on Win10
to the ruby application; I know that this works because
I tested it before on my win10 laptop. \o/

Pretty cool that libui works well on windows - that is
actually even simpler than web-apps too, because I'd
have to set up a webserver or add a lot of javascript
which I don't want to do on other people's win10
computers.

@AndyObtiva
Copy link
Owner

AndyObtiva commented Nov 24, 2021

Actually, I could perhaps use your Computer Science computational geometry algorithm knowledge to help me with this.

The main issue is that C libui does not natively support images/pixels yet, so in order to draw an image on an area, you need to specify the colors of "each pixel", meaning thousands of pixels, and for bigger images, millions of pixels. Now, to do that with libui, you would have to construct a rectangle per pixel since it does not have a pixel construct alternative. That means, it has to process millions of rectangles (and in Ruby, rectangle objects) for bigger images.

One optimization I implemented to significantly decrease the number of rectangle objects rendered through libui was by looking into each scanline in an image and seeing if there were neighboring pixels that shared the same exact color value, and then grouping them together into one rectangle. That ended up cutting down the number of pixels from 9,216 for a specific 96x96 image to about 923 shapes to render (a huge 10x speed improvement, but depends on the image having similar neighboring pixels) as reported by examples/basic_image5.rb (which is doing the work of the image control manually). That optimization is already inside the library.

Now, I worked very hard on trying to do a similar optimization vertically, by attempting to group multiple scanlines or even similarly-colored pixels vertically. Unfortunately, the logic needed to calculate such similarity on the fly turned out to be such a processor intensive task that it negated the vertical optimization. As such, I only kept the horizontal grouping-of-pixels-into-lines optimization for now.

If you can come up with a better algorithm, I would be happy to add to Glimmer DSL for LibUI. The logic for the image control shapes is at the bottom of this file (#calculate_shapes method): https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/lib/glimmer/libui/control_proxy/image_proxy.rb

Otherwise, here are a few tips for your situation that should work for the time being:

  • Decrease the size of your image from 96x96 to something much smaller like 24x24. After a certain small threshold of size, image re-rendering should be near instantaneous.
  • Remove the image and paint it with vector-graphics utilizing area shapes and text like using circle and text/string.
  • Remove the parts of the image that you could recreate with area shapes and text, and keep the part that is not easily recreatable like perhaps the "disks" only, which you could superimpose on top of the shapes with a very tiny image control for the "disks" alone.

I hope that was helpful. Let me know what works for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants