Reptorian G'MIC Filters


Decided to post another example of the fun gimmicky filter I made.


Smaller squares definitely work better. Looks goofy now. Call it goofy resampling. :stuck_out_tongue:


All inserted into G-MIC community, now I’m done with coding for a while. When I get back, I’ll go do PNG glitching and maybe find a way to support Goofy Resampling for PDN.


I’m back into coding G’MIC filter.

I figured out a workaround to Goofy Resampling issue PDN issue without needing to code unnecessarily. Basically, you just need to set vertical horizontal and then use horizontal vertical, or vice versa. This makes it so that the image dimension do not change. After that you scale the canvas and copy and paste one half to another.

Now, I’m going converting the transfer color reduced into a cli command. Should make it far more easier to code as now the transfer color reduced is literally unmaintainable at this point. When I tried adding the feature of treating reference image as a palette instead, I don’t know where to start. Hence, my motivation to convert it into a cli command to make it easier to code. So shortly, to speak, starting from scratch in that filter, le sigh.

Oh, and there is also a need to remove one useless feature in my concrete texture generator i.e background color. So, that’s on the back of my mind. Also with adding LAB colors chroma editing by A-B channel support. -2/26/2019

Did my house-keeping with new lctwp command and new pal command feature. See pull request on g’mic community for details.

Short details here -

  1. pal now accepts negative numbers. Any integers that are negative will treat one of the images as a palette. This doesn’t interfere with current filters.

Pal -999999 = pal -1 = pal i

  1. Transfer Color Reduced filter with palettes as reference has been partly transformed as a cli command with the option of using a existing image as a palette and ‘style’ transfer (Regular, Noise, ‘Thresholded’ Luminance Dithering, Horizontal Line, Vertical Line)



I want to create hardware restriction and pixelation on my lctwp command, but I am not sure how this is how it should. But there are only two solutions I can think of.

To stimulate hardware restriction

apply_tiles "autoindex {color_count},{dithering_factor},{indexing_method}"{width_of_tiles},{height_of_tiles} 

pixelate basically performs a initial downscaling using any rescaling method and upscale in the final step using nearest neighbor. This is just for stimulating old pixel art.

** Command setup - **

lctwp {stimulate_hardware_bool},{hardware_color_count},{dithering_factor},{indexing_method},{width},{height},{stimulate_pixelate_bool},{initial_rescaling},{pixel_width},{pixel_height},{palette},{transfer_style},{dithering},{alpha_count},{alpha_dithering},{style_special_effect_factor}

If stimulate_hardware_bool is true, and stimulate_pixelate_bool is false

lctwp 1,{hardware_color_count},{dithering_factor},{indexing_method},{width},{height},0,{palette},{transfer_style},{dithering},{alpha_count},{alpha_dithering},{style_special_effect_factor} where 1 is applied to stimulate_hardware_bool and 0 is applied to stimulate_pixelate

If stimulate_hardware_bool is false, and stimulate_pixelate_bool is true -

lctwp 0,1,{initial_rescaling},{pixel_width},{pixel_height},{palette},{transfer_style},{dithering},{alpha_count},{alpha_dithering},{style_special_effect_factor}

If both are true -

lctwp 1,{hardware_color_count},{dithering_factor},{indexing_method},{width},{height},1,{initial_rescaling},{pixel_width},{pixel_height},{palette},{transfer_style},{dithering},{alpha_count},{alpha_dithering},{style_special_effect_factor}

If both are false -

lctwp 0,0,{palette},{transfer_style},{dithering},{alpha_count},{alpha_dithering},{style_special_effect_factor}

lctwp is eq. to low_color_transfer_with_palette

Or should it be more like this?
lctwp {palette},{transfer_style},{dithering},{alpha_count},{alpha_dithering},{style_special_effect_factor},{stimulate_hardware_bool},{hardware_color_count},{dithering_factor},{indexing_method},{width},{height},{stimulate_pixelate_bool},{initial_rescaling},{pixel_width},{pixel_height}

This is the non-dynamic version

The non-dynamic version would be easier to work with though and less prone to error. I think I am going with the non-dynamic version as it’s easier to work with. Only thing I don’t like about non-dynamic version is having to use commas to skip variables, but that can be ignored. But, I prefer to wait for feedback before doing anything.

There’s also the idea of having dynamic option in the end.


Note that apply_tiles will have a substantially different output than with the normal filter by itself, since it is applying to local regions as opposed to global.


Yes, that’s the point. Basically, what I wanted to with stimulating hardware restriction is to force the end image to contains x amount of numbers of colors per tiles. Many older hardware has x colors per tiles restriction. The only issue with hardware restriction stimulation is the G’MIC speed of generating it. Just very slow.


Could be faster if you did it in a piece-wise fashion, saving temp files along the way. I have been meaning to explore this or at least ask about it, but alas, I don’t have time or energy to do everything that I want to do. :slight_smile:


Guess, what, I believe I am now ready to update my transfer color reduced or almost ready as everything is figured out. I changed _pal_i a bit so pal db32 = pal db32 pal -1 = pal db32 pal i

That picture looks terrible, but that’s what you probably get for emulating old system. You can see obvious hardware color restriction, and you can see that the pixels are not in 1:1 ratio.

From experiments, I think it’s a little too difficult to work with 14 variables. Best to use this with GUI.

EDIT: Better picture with C64 palette

EDIT: Fixed boundary. There’s a bug which I have no explanation for though. This filter does not always work on images, it seems to like images with more colors. When it doesn’t work, it throws out needs two layers error, and I am utterly lost at explanation for that. Then, there’s the issue of alpha. I’ll probably have to work a bit more with the alpha.

@David_Tschumperle Never mind, I fixed the bug. That was a difficult one.


Ok, I fixed the lctwp command. It’s changed to pal_t, and I added a way to enable hardware restriction on the alpha. Though with two hardware restriction stimulation, you are going to need a good PC to see it quickly. $4<2 is now allowed, 0 or 1 disable alpha while 2 or more enable alpha. Disabling alpha is ideal if you don’t need it to stimulate older hardware. I think now I’l going to wait till 2.5 is released to create a transfer color reduced replacement with the pal_t cli, or maybe I might try to experiment with the new G’MIC dynamic GUI filter soon.

Hmm, hardware color restrictions is definitely taking too long. Should I have multi-level of indexing instead instead of doing square by square? What this does is group by boxes of colors, apply indexing to each images, and then merge the result back again. Would be faster, but much harder to code. at “autoindex something,something,something”,5,5 speed generation is not acceptable. It takes me like 10 minutes to generate for a 500 px square image.


I have just solved the hardware restriction issues! Now, to wrap it up and update the pal_t filter with a much faster hardware restriction emulation.


There is only 4 colors per every 5x5 tiles. Time to render in preview in my pc. 20 seconds. The older method - 15 minutes to generate (can’t see in preview basically). It’s usable now and gives far more uniform result.


This is my take with resizing only (<1s). Results change depending on how I tweak the parameters.


One-liner challenge

Can you specify how many colors per x*y tiles with your technique? the <1s finding beats my version. I had to create two version for my pal_t script.

Here’s my version

#@cli pal_l :
#@cli : Convert palettes to layers
pal_l :
repeat $! l[$>]
if {h=1} repeat {${_iw}-1} [0] done repeat ${_iw} crop[$>] $>,0,$>,0 done else v + error "This is not a palette!" fi endl done
#@cli ahre_rgb: (eq. to auto_hardware_restriction_emulation_RGB)
ahre_rgb : auto_hardware_restriction_emulation_RGB $*
#@cli auto_hardware_restriction_emulation_RGB : precision_factor>1,tile_size_width>0,tile_size_height>0,colors_per_tiles>0,0>=dithering<=1,color_mapping_method [0 = median-cut | 1 = median-cut and k-means]
#@cli : Emulates hardware restriction automatically being based on the image.
auto_hardware_restriction_emulation_RGB :
repeat $! l[$>] remove_opacity to_rgba repeat $1 [0] done l[$1] +colormap $1,0,0 at[0] "s c f "ia" a c",$2,$3,,,,,3 index.. .,0,1 pal_l. r[1-{$1}] {w#0},{h#0},1,4,1 l[0] repeat {$1-1} [0] done endl repeat $1 l[$>,{$>+$1}] f[0] "i#0==i#1?255:0" endl done k[0-{$1-1}] to_gray endl to_rgb[0-{$1-1}] repeat $1 a[$>,$1] c done repeat $1 l[$>] +solidify 0,0,0,0,0 blend normal endl done ac "autoindex $4,$5,$6",rgb blend alpha to_rgb endl done

EDIT: Now, I updated via g’mic community. pal_t is ready for testing. Here’s a result with hardware restriction stimulation.


Looks really antique as a image. With a few edit, it’ll be looking accurate as an antique looking image. Hopefully all goes well, and if the cli command works, I’ll turn it into a gui filter.

EDIT: Also, I compared result with its android equivalent 8bitphotolab, and it turns out that 8bitphotolab wins by its trickery. G’MIC pal_t downscale, android 8bitphotolab keeps the image sharp somehow without needing to downscale. Plus, for some reason, there is no explanation whatsoever as to why cga11 with hardware restriction enabled seem to erase a color.

cga11 is cga mode 1 high

EDIT: May I need to start this filter all over again. :confused:

EDIT: I am finding that treating cga as a luminance gradient map before assigning pal_t fixes the issue with cga 4 colors modes. Maybe, I would have to add a condition to assign colors based on clut before that. Also, I might have to find a way to recreate the looks of 8bitphotolab. So conclusion, not ready to move on to making the gui filter yet. But, you’re welcome to test the new pal_t to see if I need more suggestion.

Edit: Might add upscale nearest neighbor method for pal_t. That’s what 8bitphotolab does to make it look good.

So new features will be:

  1. Pixel upscale
  2. Luminance to gradient based on 3-6 colors palette (if applicable) or by clut transfer - Makes it better with cga series.

EDIT: I have just added upscale option, and transfer_rgb option (ain’t really interested into gradient mapping as transfer_rgb does a better job). Still doesn’t always fix the issue with cga11 pal at times.


Now, the GUI filter version is happening, and it’s dynamic as well! At long last, the pal project is about to be finished.

So, when you disable hardware stimulation and/or pixel ratio or swap Method of Color Transfer, options will either disappear or be grayed out.

That being said, @David_Tschumperle I would like to document the pal commands for g’mic reference seeing it’s a noticeable new feature that could be of use for some filter writers in the future, would that be ok? Though, I do think that it needs testing before documentation to see if anything is at a wrong place or how it can be improved. I did swapped $8, and $9 on pal_t recently since it makes more sense to have 0 before the other pixel ratio variables if you want to disable it.

What can be documented at the moment
pal input_number or pal id - This generates palettes, pal -1 or pal i converts one of the two images into a palette if possible
pal_l - convert palettes to 1x1 pixel layers
pal_t only needs $8 and $9 variable swapped before it can be documented

EDIT: The GUI filter has been finished! The older transfer color reduced filter is replaced with a new version with more features. Hopefully, it’ll work fine and dandy when using it correctly as it how it suppose to be. I’ll check if it works after it is pushed though because of the way that I’m patching things from my end to github end, so I don’t know if it’ll work like in my computer. That was a very difficult project.


Next filter. Hmmmm…


I received a bug claim where my emboss-relief filter does not work with relief mode set on inside GIMP. As I do not use GIMP nor has G’MIC installed there, can someone confirm? Use the latest version of G’MIC though and click update.


Sorry, I cannot check. I have an older plugin version.

(Silvio) #87


Here are my specs:
Windows 10 (64 bit)
Gimp 2.10.4
G’MIC 2.5.3

As soon as I click on Ok to try the filter:
Reptorian > Emboss-relief (standard default: no change applied) an error always pops up:
*** Error in ./fx_emboss_relief/*repeat/*local/ *** Command ‘l’: Invalid selection [-2] (contains index ‘-2’, not in range -1…0)
Afterwards, the g’mic window with the filter disappears (crashes?) and I am back to GIMP. Needless to say the filter is not applied on my image (1 single layer)

BTW, this filter has no short description and I do not know what it is supposed to do, altough, from its label, I suppose it should apply some sort of embossing on my image :slight_smile:


It’s based off Paint.NET embossing/relief technique. Hmm, it works fine and dandy on Paint.NET and Krita. I guess I’m gonna have to change the code on the filter to make sure that it works on all of those softwares. Though, the fact that it works on Krita and Paint.NET just fine, but not on GIMP concerns me into thinking I may have stumbled into something here. I guess I’ll have to find a way to install GIMP and G’MIC inside Windows to verify that changes to code works. @David_Tschumperle - Is there a bug within GIMP G’MIC side of thing?

(Silvio) #89

Hello @Reptorian,

There is something weird going on with the 3 links you provided in your previous message, namely “Paint.NET

On every one of them when you click to open the corresponding web-page you are directed to this web-page:
On the contrary, if you right click (copy web-link command) with your mouse on these 3 links you get the correct web-page, that is:

I have tried with Firefox 66.0.1 (Windows 10)

EDIT: strangely enough, this occurs even with my own current post.
I am always pointed to the standard and architecutal web-page whenever I click on the Paint.NET link. Not the web-site…