jankovicsandras / imagetracerjs

Simple raster image tracer and vectorizer written in JavaScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Intermittent slowdown in `colorquantization` function

jminardi opened this issue · comments

I am using the following version of ImageTracer:

https://cdn.jsdelivr.net/npm/imagetracerjs@1.2.5/imagetracer_v1.2.5.min.js

I am using ImageTracer.imagedataToSVG with the following settings:

var svgstr = ImageTracer.imagedataToSVG(
  imageData,
  { blurradius:5, blurdelta: 256, colorsampling:0, colorquantcycles:1,
    numberofcolors:2, scale: 0.5 },
);

Most of the time this call takes about 400ms to execute. However, sometimes (either after some amount of time or a certain number of repeated calls) the function call takes about 15 seconds to execute. Once the function starts taking this long to execute, it always does until I reload the page. This long execution also happens with the same imageData that previously had been taking 400ms. The imageData is pulled from a canvas like so:

var ctx = document.getElementById('c').getContext('2d'); // load context of canvas
var imageData = ctx.getImageData(540, 768, 1920, 192)

Here are some screenshots from the chrome dev console, the first is with the expected exection time, and the second is with the long execution time.

Screen Shot 2020-03-30 at 1 45 08 AM

Screen Shot 2020-03-30 at 1 42 14 AM

Please let me know if there is more data I can provide or other experiments I can run to help narrow down the issue.

Hi,

As I understand, you don't get errors, get correct results in the end, but it takes a lot of time. We need to find out if it's a problem with ImageTracer or something else. I'm not familiar with the chrome dev console, but does the 2. image show agressive garbage collecting, which takes a lot of time? In other words: maybe you are (almost) running out of memory, which leads to slowdown.

Can you try these and tell me the results?

  • trace a much smaller image
  • trace without blur
  • use Firefox

You are correct, I eventually get the correct result in the end. I do not think the problem is with aggressive garbage collection, but I can't be sure. I also don't use Chrome I just started using it here because they have a Vue development plugin (I usually use Safari).

I tried with an all white image and still get the issue.

I tried with a smaller image and was not able to reproduce the issue

I without blur (at the original image size) and also was not able to reproduce the issue.

I tried on Firefox but was unable to reproduce the issue at all. Interestingly, the task took about 25% of the time in Firefox as compared to Chrome.

Is there any way for me to reset the state or clear out the data of ImageTracer? How could I mimic a fresh reload of the page every time I call the function?

Another note: Using macOS's Activity Monitor app I do not see any increase in memory usage when the hang is happening, but I do see a process called Google Chrome Helper (Renderer) jump to the top of the list with 100% CPU usage.

I also modified my app a bit and added a checkbox to apply the blur setting. When I am in the hanging state I can remove the blur and then get back to fast rendering without reloading. When I reactivate the blur I get back to the 15-20 second hang (until I reload the page).

I'm happy to hear that you found alternatives that work, e.g. Firefox. I develop and test ImageTracer mostly with Firefox as well. I don't see any problem with ImageTracer itself, I suspect the cause of the slowdown might be in Chrome or some other configuration, which I can't troubleshoot. I close the Issue, but feel free to reopen it, if you have evidence that the problem is with ImageTracer.

Hi @jankovicsandras I am still running into this issue with Chrome and since many of my users are on Chrome I was hoping to figure something out. Can you help me with some sort of workaround?

Is there any internal state or objects I could clear out to reset the ImageTracer library? I am hoping to effectively "reload" the library.

Hi

Here's some wild guessing which might help. I'm sorry, but I have no time to test this now.

At Line 1081 there's new Uint8ClampedArray. Is it possible, the this temporary array doesn't get freed and garbage collected? You can try to replace var with let at Line 1081 or insert himgd = null; to Line 1127.

Hi @jankovicsandras thank you for helping me with this. Unfortunately those two fixes don't seem to work. I will keep digging into the issue and let you know if I find any solutions.

@jminardi : can you please test this PR? fix: replace Math.abs with tenary statements #48

0798079