Windows Gradient Converter, Apophysis to Kalle's Fraktaler

  • 19 Replies
  • 664 Views

0 Members and 1 Guest are viewing this topic.

Offline Mandel Meute

  • *
  • Fractal Freshman
  • *
  • Posts: 5
« on: July 13, 2019, 05:16:51 PM »
Hello everyone,

over the past few days, padleywood and I created a program that allows you to convert a .ugr or .gradient file to a .kfr or .kfp file.
Since there is an abundance of Apophysis gradient packs out there, selecting a palette for a Kalle's Fraktaler project should no longer be a problem.

As of version 1.0.5, the program can also convert from Fractorium .xml files and Fractint .map files!
With version 1.0.6 you can now select multiple files when loading Fractint .map files (currently limited to 1024 per load).

Download Version 1.0.7

Instructions:
To use the program, simply select the type of file you would like to convert and load a respective file or paste gradient data from your clipboard.
Your input will then be processed, which might take some time. If your input was a gradient pack, you may explore it and select the one you wish to convert by clicking on it. To convert only the selected gradient, hit 'Convert selected'. If you want to convert all currently loaded gradients, hit 'Convert all' instead.
Further information can be found below or by clicking on the '?' buttons in the application.

More detailed information:
The 'Sequence Sort' and 'Index Sort' settings allow you to alter between two different methods of ordering the colours.
Basically, an index is assigned to each colour. With Index Sort, this index is used to order the colours. When using Sequence Sort, merely the order in which the colours are listed is relevant. Thus, Index Sort might be closer to the original input, while Sequence Sort will result in more evenly spaced colours.
When handling gradients generated using Apophysis though, the difference between the two will barely be noticeable, so use the one which you like the most.
The 'Use 1024 Colours' option is only applicable to Sequence Sort. In Kalle's Fraktaler, a palette can have between 1 and 1024 colours. Most gradient packs will only have 256 colours though, so you might want to have just these 256 colours in Kalle's Fraktaler. Leaving the option unchecked will do just that. When it is checked though, the output will have the maximum of 1024 colours.

Padleywood helped me to create this program, which I am very grateful for. You can check out his channel here.

If you encounter any inconvenience or problem with the program, please inform me. Feedback is highly appreciated.

Gradient Packs
Fracatint maps (Thanks, blob!)

Optional 1.0.7 release with an option to darken the GUI. Not recommended.

Mandel Meute


Linkback: https://fractalforums.org/programming/11/windows-gradient-converter-apophysis-to-kalles-fraktaler/2934/
« Last Edit: August 19, 2019, 07:41:17 PM by Mandel Meute »

Offline Fraktalist

  • *
  • Administrator
  • *******
  • Strange Attractor
  • Posts: 1143
« Reply #1 on: July 13, 2019, 05:26:09 PM »
wow, guys thats awesome!!!
I'll definitely use this a lot!  :)

Also: Welcome to the forum !
« Last Edit: July 14, 2019, 03:01:48 PM by Fraktalist »

Offline Fraktalist

  • *
  • Administrator
  • *******
  • Strange Attractor
  • Posts: 1143
« Reply #2 on: July 14, 2019, 02:17:27 PM »
okay, first quick test, this is really great. I didn't know I was missing such a tool.
I'll quickly write down quick thoughts/ideas (unfiltered, not diplomatic, so please don't be offendend)

-remove the backround image where all the settings are, very hard to read the text. (or make it a brighter/greyer one, for better contrast with font
-also remove background image for pack-preset selection, looks nice but it distracts from the actual palette.

-text gradient display far too large for my taste,  80% of GUI used for a feature with little practical use (for me)
(also, if you loaded a pack, the list will always only show the first palette in the pack, even if you switch to other palettes with the arrows)
I suggest you remove it completely and instead just add a button "paste gradient from clipboard"
-->cooler would be: instead add a "multiview" that shows all gradients in a pack visually in clickable rows, like this. much easier navigation through a pack.


-request: batch convert for all gradients in a pack. naming: let me manually give name and automatically add numbers

-make *.kfp default export, usually you want to try a new palette for an existing location and not load a kfr with resetted zoom-settings.
edit: ah, I see, once you manually changed saving to kfp it will continue to do that. good enough.

-probably complicated: give ability to preview in context. choose a good location and then map the gradient to it, maybe add a way to adjust divide iteration. add this display below the gradient viewer, update in realtime when switching through

-Auto-Assign Filenames from the apophysis preset name in save-dialog.

-re-arrange GUI more logically in rows, imho this would make more sense:
Row 1: Load File (+"paste gradient from clipboard" button) + Refresh button
Row 2: Pack-Preset selector
Row 3: Preview display
Row 4: Convert & save (+Batch Convert)





« Last Edit: July 14, 2019, 07:47:40 PM by Fraktalist »

Offline blob

  • *
  • Fractal Fanatic
  • ***
  • Posts: 22
« Reply #3 on: July 14, 2019, 05:17:42 PM »
Nice tool but no matter what I do I always get a 1024 colors output from a 400 colors input which seems the default number of colors in apo gradients.

It would be nice if your tool could convert fractint map files too. :)

Offline Fraktalist

  • *
  • Administrator
  • *******
  • Strange Attractor
  • Posts: 1143
« Reply #4 on: July 14, 2019, 07:46:36 PM »
Nice tool but no matter what I do I always get a 1024 colors output from a 400 colors input which seems the default number of colors in apo gradients.
When I switch to "sequence sort" before conversion, "use 1024 colours" unchecked, I get the actual number of colours.

Offline blob

  • *
  • Fractal Fanatic
  • ***
  • Posts: 22
« Reply #5 on: July 14, 2019, 11:32:19 PM »
When I switch to "sequence sort" before conversion, "use 1024 colours" unchecked, I get the actual number of colours.

Yes, this works, thanks.

Online claude

  • *
  • 3f
  • ******
  • Posts: 1257
    • mathr.co.uk
« Reply #6 on: July 15, 2019, 07:31:45 PM »
Great idea!  Would be awesome to integrate it within KF itself, so you wouldn't need an external program.  If you would be willing send me your source code and agreement to license it publicly under AGPL3+ it would make it easier for me, otherwise I can try to code something myself for the next release (no time scale, but I don't have much else to do from mid-August).  The .ugr/.gradient file format seems quite simple to reverse engineer, though I haven't found a specification anywhere.  Could also be interesting to support flam3 XML, or Photoshop / GIMP gradient files.

Another thing that I want to do is lift the limit of 1024 colours, that is hardcoded in various places.  Doing that without changing the appearance of existing images might be hard, but I'll try to keep backward compatible.  But I don't know how the Windows GUI will cope with eg 1M colour swatches in the central column of the colour dialog.  Can only try it and find out!

Offline Mandel Meute

  • *
  • Fractal Freshman
  • *
  • Posts: 5
« Reply #7 on: July 17, 2019, 08:36:21 PM »
Thank you all for the support and feedback!
I updated the post to the new version, 1.0.4.

It has a bunch of new features and improvements, most of which were due to Fraktalist's thorough feedback and ideas. Thanks for that!
I removed the background images and the input text display.
The original preview was replaced by a new one, which now displays all gradients in a pack (at the cost of a slightly higher processing time).
I also added the batch convert feature, although I didn't include a custom naming option yet (mostly because the UI is already pretty crammed) but instead a lot of different naming options.

The default extension is now .kfp, although that shouldn't have been an issue anyways. Originally, I wanted to overwrite only the colours part in a file, but due to a little error that did not work out in the end. I fixed that, and now you can overwrite existing .kfr and .kfp files' colours without changing other data. However, that does not work with batch convert.

The filename for a single conversion will now be the gradient title by default and the UI was also improved.

-probably complicated: give ability to preview in context. choose a good location and then map the gradient to it, maybe add a way to adjust divide iteration. add this display below the gradient viewer, update in realtime when switching through

Yeah, this is complicated. I already tried creating a primitive Mandelbrot explorer using the same IDE, and it turned out to be rather slow, even at low canvas size and iteration count.
A faster idea would be to pre-render a part of the set and save the iteration count for each pixel. Then it would be possible to insert the colours at runtime at a moderate speed. If anyone has a suggestion for an adequate location, feel free to share it with me. I will see what I can do.

If you would like me to make more file types available for conversion, please message me with at least one file and a visualisation of it. I will try to get them in for the next update.

It would be great to integrate this within KF! The IDE I used to create the program is unfortunately for Delphi / Free Pascal.
I will try to translate the relevant parts of the code though and explain how it works:

The .ugr and .gradient files don't have any difference except for the extension.
Here is a part of the gradient pack 'Teuns FGP' by Teuns:

Code: [Select]
Coffee_in_a_red_mug {
gradient:
 title="Coffee_in_a_red_mug" smooth=no
 index=0 color=3819102
 index=2 color=2897741
 index=3 color=1515586
 index=5 color=395066

 ...

 index=393 color=1906811
 index=394 color=2104443
 index=396 color=2439020
 index=397 color=3226207
 index=399 color=3161691

}

I extracted the relevant data (title, indices, colours) by going through the input string and watching for certain characters and character combinations (e.g. '  "  ' marks the beginning of the title).

The colour format is essentially a Hex BGR value converted to decimal.
That means, in order to get the RGB values of '3819102' you would first have to convert the value to hexadecimal, which would look like this: '3A465E'. The first two digits are the blue value, the middle two are the green value and the last two are the red value.
Converting back to decimal, the extracted colour would look like this (R,G,B): 94, 70, 58.
Using code, it could be expressed like this (no specific language):

Code: [Select]
int[] colours; //Has the input colour values

int[] red;
int[] green; //Store the extracted colour values
int[] blue;

string hexString;

for (int i = 0; i < colours.length; i++) //Loop through all the input colours
{
hexString = DecToHex(colours[i]); //Convert the input to hexadecimal
red[i] = HexToDec(hexString[4] + hexString[5]);
green[i] = HexToDec(hexString[2] + hexString[3]); //Extract the colour values and re-order to RGB
blue[i] = HexToDec(hexString[0] + hexString[1]);
}

Once we have extracted all the colours, we can create the gradient with them. This is done by linear interpolation.
Basically, we want to evenly scatter the colours across our output, and then 'fill in the gaps'.
Here is the code:

Code: [Select]
public void SequenceDraw(color[] colours, int amount) { //'colours' contains all ordered colours (RGB), amount is the amount of colours the output is supposed to have

int R;
int G; //The colour values in RGB that will be calculated
int B;

int XPosition; //Stores the horizontal location

bool[] filled; //assuming that booleans are initialised 'false', filled stores, if a pixel (or similar, depending on the context) already has a colour assigned to it


float segment = Amount/(colours.Length-1); //segment is the distance between two colours. E.g. if you have 26 colours and want to have an output of length 75, each segment will be 3 units
//the '-1' is because we don't want to add another segment after the last colours

for (int i = 0; i < (colours.length -  1); i++){ //Now we actually begin drawing. We loop through all the colours, but ignore the last one ('-1') because the last one should not have another segment attached

for (int j = 0; j <= ceil(Segment); j++) { //We loop through each unit/pixel within the length of a segment. We round up so that we don't miss out on any pixels/units

R = round((( (colours[i+1].Red - colours[i].Red) / Segment)*j) + colours[i].Red); //These three lines actually calculate the value at that specific position
G = round((( (colours[i+1].Green- colours[i].Green) / Segment)*j) + colours[i].Green);  //The formula can be derived and understood when you think a little bit about it,
B = round((( (colours[i+1].Blue - colours[i].Blue) / Segment)*j) + colours[i].Blue); //but I also created a Desmos graph to visualise it: https://www.desmos.com/calculator/n7ak6xbooi

XPosition = ceil((segment) * i) + j; //Calculate the position of the colour in the output

if (filled[XPosition]) { //Now we interpolate linearly, in case ther already is a colour where we want to draw:
R = (R + Output[XPosition].Red) / 2;
G = (G + Output[XPosition].Green) / 2; //Basically, if there already is a colour present,
B = (B + Output[XPosition].Blue) / 2; //we take the intermediate value of it and out new colour, and store it as our new colour
} else {
filled[XPosition] = true;
};

Output[XPosition] = RGBToColor(R, G, B); //And finally, we convert our single values to the output colour at that position
}
}
}

public void IndexDraw(color[] colours, int[] indices) { //'colours' contains all ordered colours (RGB), indices contains the corresponding indices

int R;
int G; //The colour values in RGB that will be calculated
int B;

float segment; //This time, the segment won't have a rigid value for each colour, so we will have to calculate it in between each one

int XPosition; //Stores the horizontal location

bool[] filled; //assuming that booleans are initialised 'false', filled stores, if a pixel (or similar, depending on the context) already has a colour assigned to it

int MaxIndex = indices[indices.length - 1]; //Stores the last index value as the highest index value


for (int i = 0; i < (colours.length -  1); i++){ //Now we actually begin drawing. We loop through all the colours, but ignore the last one ('-1') because the last one should not have another segment attached

Segment = ((indices[i+1] - indices[i]) / MaxIndex) * 1024; //Before calculating the colours, we have to calculate the segment length. We do that by determining what fraction of the whole output the segment will cover, and multiply that by the output length, in this case 1024

for (int j = 0; j <= floor(Segment); j++) { //We loop through each unit/pixel within the length of a segment. We round down because otherwise ugly colour glitches would appear

R = round((( (colours[i+1].Red - colours[i].Red) / Segment)*j) + colours[i].Red); //These three lines actually calculate the value at that specific position
G = round((( (colours[i+1].Green- colours[i].Green) / Segment)*j) + colours[i].Green);  //The formula can be derived and understood when you think a little bit about it,
B = round((( (colours[i+1].Blue - colours[i].Blue) / Segment)*j) + colours[i].Blue); //but I also created a Desmos graph to visualise it: https://www.desmos.com/calculator/n7ak6xbooi

XPosition = ceil(( (indices[i]/MaxIndex) * 1024) + j); //Calculate the position of the colour in the output

if (filled[XPosition]) { //Now we interpolate linearly, in case ther already is a colour where we want to draw:
R = (R + Output[XPosition].Red) / 2;
G = (G + Output[XPosition].Green) / 2; //Basically, if there already is a colour present,
B = (B + Output[XPosition].Blue) / 2; //we take the intermediate value of it and out new colour, and store it as our new colour
} else {
filled[XPosition] = true;
};

Output[XPosition] = RGBToColor(R, G, B); //And finally, we convert our single values to the output colour at that position
}
}
}

I hope this helps and that the code has no syntax errors.
You can use it all you want, no credit necessary.

Lifting the colour limit would be awesome. This would allow for much less monotonous Mandelbrot zoom videos.

Online claude

  • *
  • 3f
  • ******
  • Posts: 1257
    • mathr.co.uk
« Reply #8 on: July 17, 2019, 10:47:02 PM »
Yeah, this is complicated. I already tried creating a primitive Mandelbrot explorer using the same IDE, and it turned out to be rather slow, even at low canvas size and iteration count.
A faster idea would be to pre-render a part of the set and save the iteration count for each pixel. Then it would be possible to insert the colours at runtime at a moderate speed. If anyone has a suggestion for an adequate location, feel free to share it with me. I will see what I can do.
You should be able to load the iteration data from a KFB map file as saved by KF.  But KF's colouring code is a bit idiosyncratic and only exists in the KF executable source code.  I do plan a feature whereby you can invoke KF noninteractively (command line) with inputs a KFB map and a KFP palette to output a colourized image file, perhaps when i've done that you could use that mode in your program?

Quote
If you would like me to make more file types available for conversion, please message me with at least one file and a visualisation of it. I will try to get them in for the next update.

These are two examples with slightly different syntax.
https://bitbucket.org/mfeemster/fractorium/src/master/Data/user-palettes.xml
https://bitbucket.org/mfeemster/fractorium/src/master/Data/flam3-palettes.xml
I guess check how fractorium displays them, I don't have any example output.
no formal specification afaict but the original parser source code is here:
https://github.com/scottdraves/flam3/blob/master/parser.c#L595
https://github.com/scottdraves/flam3/blob/master/parser.c#L83

Quote
It would be great to integrate this within KF! The IDE I used to create the program is unfortunately for Delphi / Free Pascal.
Oh.  A pity for me!

Quote
I will try to translate the relevant parts of the code though and explain how it works:
Reading/converting the palette is the easy and fun part - I was hoping not to have to do the Windows GUI programming...

Quote
The colour format is essentially a Hex BGR value converted to decimal.
That means, in order to get the RGB values of '3819102' you would first have to convert the value to hexadecimal, which would look like this: '3A465E'. The first two digits are the blue value, the middle two are the green value and the last two are the red value.
Converting back to decimal, the extracted colour would look like this (R,G,B): 94, 70, 58.
I would do the conversion using >> and & operators, should be faster and less error prone.  Don't know if that is possible in Delphi / Free Pascal.

Quote
You can use it all you want, no credit necessary.
ok

Offline blob

  • *
  • Fractal Fanatic
  • ***
  • Posts: 22
« Reply #9 on: July 17, 2019, 11:43:52 PM »
New version is great, not only as a conversion tool but as a standalone tool for visualizing gradient collections.  :thumbs:

Please support also Fractint map format, it's 256 lines with one RGB triplet per line, possibly loading many at once by parsing the content of a folder.

There is a big collection of them to download on the softology blog for example: https://softologyblog.wordpress.com/tag/color-palettes/

What makes them interesting IMHO is that many are very different in style to the always kinda similar algorithmically generated apo ones.

Online claude

  • *
  • 3f
  • ******
  • Posts: 1257
    • mathr.co.uk
« Reply #10 on: July 18, 2019, 09:41:25 PM »
I do plan a feature whereby you can invoke KF noninteractively (command line) with inputs a KFB map and a KFP palette to output a colourized image file, perhaps when i've done that you could use that mode in your program?
This feature is implemented in kf-2.14.6 (released today).
Usage: kf.exe --load-map input.kfb --load-palette palette.kfp --save-png output.png
Check kf.exe --help for more options.
https://wiki.freepascal.org/Executing_External_Programs seems relevant, you can wait until the program has finished with successful exit code then load the output.png

Offline Fraktalist

  • *
  • Administrator
  • *******
  • Strange Attractor
  • Posts: 1143
« Reply #11 on: July 28, 2019, 11:37:40 AM »
awesome update!  :thumbs: :yes:
Great to see my feedback implemented! :)

another little suggestion: "dark mode" I feel I can work better with colors when the GUI background isn't in the standard bright windows grey.


Would love to see this directly in KF!
Ahh, it's things like this that I love most about this forum. Collaborations, open for feedback, people just developing things and giving it for free to the community.
Love you guys!

Offline Mandel Meute

  • *
  • Fractal Freshman
  • *
  • Posts: 5
« Reply #12 on: August 12, 2019, 02:43:16 PM »
Version 1.0.5 is now available. The program now supports conversion from Fractorium .xml and Fractint .map files. Additional testing is very appreciated.
At the bottom of the post, there is an alternative version that includes a 'Dark Mode' button. Unfortunately, the best I was able to do was change the colours of the bevels and background. Most text colours can not be altered, and the colour of the buttons have met a similar fate. As a result of that, the dark GUI does not look very good, that's why the dark mode is not included in the main release.

The next version will probably come with the selection of multiple files, allowing to mass convert .map files much faster. It would be a lot easier for me to only include this feature for .map files, since these are always separate. If e.g. included for .gradient files as well, this would add another dimension of complexity regarding structure. With .map files, I can treat multiple files as if they would belong to the same pack.

Offline Mandel Meute

  • *
  • Fractal Freshman
  • *
  • Posts: 5
« Reply #13 on: August 17, 2019, 07:52:56 PM »
Version 1.0.6 is now available. Multiple file selection is now supported for Fractint .map files, however, you can not select more than 1024 files due to internal limits. If you would like to convert many .gradient, .ugr or Fractorium .xml files at once, it would probably be faster to just merge them into one long, singular file (paste each file's content below one another).

I converted all of the Vision of Chaos palettes into .kfp palettes to spare anyone who just wanted to use all of these in KF some time. To quote the supplier of the original palettes: "No copyright on them so do with them as you wish.". If you are interested in their work, visit their website.

Download the Vision of Chaos palettes pre-converted to .kfp files

Offline gerrit

  • *
  • 3f
  • ******
  • Posts: 1830
« Reply #14 on: August 17, 2019, 08:13:07 PM »
Long time ago I converted all the MATLAB gradients to kfp. If anyone wants I can make hem available.


xx
Kalle?s Fraktaler on Mobile?

Started by Chronicler1701 on Kalles Fraktaler

3 Replies
353 Views
Last post August 26, 2019, 08:40:51 PM
by claude
clip
numerical aproximation of the scalar field gradient

Started by Adam Majewski on Programming

0 Replies
237 Views
Last post July 29, 2018, 09:22:17 PM
by Adam Majewski
xx
Apophysis on mac

Started by HalluFract on Other

2 Replies
470 Views
Last post March 05, 2018, 08:25:50 PM
by solarhythmia
xx
Apophysis Forum?

Started by who8mypnuts on Discuss Fractalforums

3 Replies
396 Views
Last post June 07, 2018, 01:30:21 PM
by who8mypnuts
clip
Apophysis fractals by Julofi

Started by julofi on Image Threads

13 Replies
552 Views
Last post July 07, 2018, 02:37:59 PM
by julofi