Remove/clean jaggy function

Pretty self explanatory. I don’t really like using the pixel perfect option for the brush, yet there are still situations where you need to clean something after the fact. It would be nice if there was a function that did the same thing to already existing lines. It wouldn’t do a perfect job since it can’t know the best artistic choice of pixel to remove, but it would serve as a good starting point for further cleaning.

i wonder if there’s some algorithm for this already. i didn’t find anything yet, but i’m sure this could be done with script. i made a quick hand-made test:
_temp-cleanup2 _temp-cleanup2-source
and it seems like it could work rather fine.
the rules are simple:

  • check colour of pixel on position n. if its colour is selected colour c, then:
  • check position n+1 in specified direction
  • if there’s no colour c on that position, do nothing
  • if there is c, move to n+1 and check all other +1 positions except the position n - if there’s c present on any of these positions[*], delete n+1 pixel.
  • move to n+1 and repeat

in this example there are only two problematic cases:
– ‘down’ direction: erasing one pixel at the right end of the line (that may or may not be what user wanted)
– ‘left’ direction: leaving out one pixel in the same area instead of erasing it. this issue can be solved by going through the process at least twice in both horizontal and vertical directions. or possibly all of them - as seen on examples, the order of selected directions would matter.

this would of course work only on layers with just lines and transparency.
if the line is surrounded by other colours then the process would be more complex, as it would have to check other areas for colours and then change the colour of a pixel instead of deleting it.
also when applied to filled areas instead of lines, it could give really bad results.

i would try to write this script, but i am too busy this month.
meanwhile someone else may find it interesting enough to write it?

edit: [*] this is actually incorrect.

I assume it will be better to analyze normal vector (or just angle) at each selected color pixel as distance-weighted average of perpendicular vectors (or angles) of surrouning pixels of same color (only connected i.e. use spread fill to find them), then (one at a time) find and remove most off-line “jaggy” pixels (compare by sum of distance-weighted distances to angled line of each of surrounding pixels) until there will be no pixels with “jaggy” neightbours.

you might be right, but i don’t know anything about vectors. wouldn’t it be more time consuming though? the scripts aren’t very fast.

Not really. Most time consuming will be pixels scanning process to collect them. After that we’ll have array of all pixels with information about them (averaged angle, number of connections around) to find pixels to remove in continous passes.

We also can act in Selection only to avoid touching too much and restricting what could be modified.

Also maybe use simpler approach and just always find and compare next two horizontal or vertical pixels which form two side connectivity (with one or two pixels at each side). And then decide which one to remove by comparing distances averaged angles lines of surrounding pixels and pick one which is most off-line.

i see. would you give it a try?

I may implement the algorithm, but without user interface, color picking and filtering by Selection. My implementation will always look for specific color and at current active layer and frame. Would you add those features after that if the algorithm will work?


sure thing!


I know nothing about scripting this sort of thing but,
I think you’re right that doing it to the selected color is the best bet. Would it be possible to select everything of that color on the layer (like using wand), cut it, put it on it’s own layer with transparency, do the effect, and then paste/merge the contents back to the original layer? Internally as part of the process, I mean.

It may also make sense to add an option that adds the cleaned lines to a new layer and keeps it separate, so that you can choose what to do with it.

Though in terms of practical use, I can also imagine it being useful if you can lasso something and hit a hotkey without a window even popping up, fixing only that spot.

In general it would be nice if you could save a filter’s settings to a hotkey, so that you can do things like “apply outline” with presets, without the window ever even coming up. Though I guess that’s a seperate feature in and of itself.

well, i’m not a programmer, so… yeah :]]
however, the gui-less version which would take the current foreground colour as input is no problem.
i’ve never used it before, but it seems like we can pack the script as a plugin, which should be able to store preferences. one can add hotkeys to both scripts and plugins, so thats fine.
and i’d say lifting the lines to another layer should be doable as well.
but let’s not get ahead of ourselves. first we need basic functionality and then we’ll see what to do next with it.

First working version ( - Google Drive

It looks at current sprite current cel and searches for color cc(0,0,0,255) and replaces it with color ct(255,0,0,255) (red color for easy testing) at jaggy places.

You may add panel with colors selection or make a gui-less version that uses foreground and background colors.


you’re super fast! thanks

no ui - uses foreground and background colours for detection and replacement: eg_jagger - no ui -

simple ui - two colours, one button: eg_jagger - simple ui -

no ui on selection: eg_jagger - no ui - selection -
note: this version works correctly only on rectangular selections. unsurprisingly, selection made with lasso tool is treated as rectangle.


Now let’s wait for Kyrieru to evaluate our efforts =)

1 Like

i still plan to tweak selection version when i get a bit more time. i think the content outside of selection can be filtered out through selection:contains(point)
but other than that it seems to work just great. i didn’t think i’d need something like this until now :]


Quick pixel sketching made fun :]

1 Like

Thanks guys, I’ll take a look.

I think that there’s times when you would want it to auto handle layers and deleting of the jaggy pixels (aka select, hit the hotkey, and they’re just gone), whereas the current behavior of setting the pixels to red is useful in other situations.