AROS World Exec
Development => Development (General) => Topic started by: miker1264 on February 17, 2021, 01:45:36 AM
-
There are many graphics effects and transformations that can be introduced to AROS programs.
One such transformation is something I have wanted to do for some time but I couldn't begin to understand how to do it. It is called HSL Hue Rotation where a color group transforms to another one such as Blue to Green. How does that happen?
The IconEdit program I'm working on may be a great place to experiment with this. I only need two basic inputs which can be determined by mouse coordinates in the window. For ARGB images there is no colormap so I will display a colorwheel instead. From the menu select "Hue Rotate" to start the function. Select a pixel in the image in the source color group. Then pick a point on the colorwheel graphic as the second color value.
The central conversion is from RGB Colorspace to HSL and back again for each color in the original image. I found two such Algorithms in C++ but it is basically the same code for C also. They are RgbToHsl and HslToRgb.
Once we have the source color and the reference color it's simple conversion and mathematics. The Hue is the base color value but in HSL it is actually a degree measurement from the HSL Colorwheel. So we find the degrees value for both hues to find the difference in rotation. For example, if we have a nice blue png drawer icon image and we select green as the reference color from the colorwheel then the degrees are roughly 260 for blue and 120 for green. So the rotation value is positive 220 or negative 140. This rotation is applied to each pixel in the original image trasnforming the blue drawer icon to a nice green one!
Note that every pixel is changed even ones we want to keep. To preserve underlying pixel values we use a white pixel mask but that's another topic for another day! :)
-
How does that happen?
That is a nice summary of how that works.
What i am uncertain about though is if that was an explanation that requires some confirmation for you or if there is an actual question in there (sorry, i did not had my cup-a-tea yet :) ) ?
We have a colorwheel, for an example see https://github.com/deadw00d/AROS/blob/master/developer/demos/colorwheel.c (https://github.com/deadw00d/AROS/blob/master/developer/demos/colorwheel.c)
For manipulating the individual pixels you can have a look at directory https://github.com/deadw00d/AROS/tree/master/developer/debug/test/graphics (https://github.com/deadw00d/AROS/tree/master/developer/debug/test/graphics)
There are two specific examples there (sorry, i can't recall their exact names) that opens a window and 'fades' the colours depending on the location of the mouse pointer. One doing so using matte colours and another doing so transparently.
( I linked to deadw00ds github but those files could be taken from any AROS repository ).
I take it the transformation from rgb to hsl (and back again) is known to you. Which only leaves the actual rotation (and i assume the c example you are using takes care of that part) ?
Note that every pixel is changed even ones we want to keep. To preserve underlying pixel values we use a white pixel mask but that's another topic for another day! :)
Ok, so are you talking about rotating certain parts of the picture only then ? Because if you rotate in hsl colorspace (for the whole picture) then the only thing you need to keep track of is the rotating angle (and rotate back when restoring the original image colors). Yes, there is an error-margin there that screw things up, but multiplications are cheap ;) (but perhaps i misunderstood what you wrote).
-
Ah the AROS Colorwheel or ColorRequester.
Maybe there is code there for returning a color value in rgb ?
I have both algorithms for rgb to hsl and hsl back to rgb. I just need ReadPixel to return an rgb value I can use instead of ULONG pen value.
I've already done color rotation by swapping color channels.
Imagine swapping all 'g' values for 'b' values such that each rgb is now 'rbg'. The blue image turns green. :)
I just don't know the exact color rotation. I will come up with a test for that to make a tables of rotation values.
-
Ah the AROS Colorwheel or ColorRequester.
Not meaning that your own colorwheel implementation is any less than this one. I mentioned it because it is probably more standard and convenient to use for your use-case.
Maybe there is code there for returning a color value in rgb ?
I have both algorithms for rgb to hsl and hsl back to rgb. I just need ReadPixel to return an rgb value I can use instead of ULONG pen value.
That is why i directed you to those two examples that i mentioned ;)
Perhaps even better, some documentation, see https://en.wikibooks.org/wiki/Aros/Developer/Docs/Libraries/CGFX (readrgbpixel/writergbpixel).
Working with something other then planar bitmaps requires a bit of a different approach. You can determine the 'type' of the bitmap when you load it and act accordingly (so that you are able to support both planar and rgb bitmaps, or ignore planar altogether if you wish to do so).
I've already done color rotation by swapping color channels.
Imagine swapping all 'g' values for 'b' values such that each rgb is now 'rbg'. The blue image turns green. :)
Yeah, i am familiar with the concept of messing up the color-values ... wrongfully ;D
-
:Pmagorium
One day I was working with the Amiga Clown. You may know him. :)
I was trying to get the right colormap for an ilbm. But all I had for reference was a png PLTE chunk. So natural I used a hex editor and copied the color values. BUT I forgot that png puts the chunksize before or after the chunkid, but ilbm was different.
So my ilbm colormap was 4 bytes off...imagine my horror and surprise when the clown turned GREEN.
But why did it turn green? We shifted the colormap 4 bytes so we disregard the the first rgb. So we basically shifted it 1 byte to the right so r becomes g, g becomes b, and b becomes r. It shifted.
It's almost like you know what I'm thinking. :)
Yes. I intend to use ReadRGBPixel and compare output to ReadPixel.
Of course, the HSL Colorwheel I refer to is different than a color requester.
I suppose the interesting question is: Can I use HSL Color Rotation on an ILBM image then save it as ILBM ? Yes. Because it is an indexed image. And we only need to change the rgb colormap values. That would be super exciting! :)
-
Success! The RGB to HSL algorithms I'm using are working. And my IntuiText is also working for Icon Class. I wish I could change the font and whether it is bold or italic.
In the screenshot you see the rgb color sample. Then it is converted to hsl. You see those values. As a test I converted hsl back to rgb to compare.
The hue value is one degree off from the on-line calculator. I suspect it is a rounding error in the calculation for hue. The value is stored as a double but it gets converted to int.
In the real world if we see 35.59 we would naturally Round Up to 36. But when you cast as (int) it truncates the value to just 35. A true method to Round Up/Round Down is needed to correct the Off by One Error. That also throws off the G value in the output rgb value as you can see. It's very precise mathematics.
-
Here is the conversion code I am using. It is heavily modified by me to fit the icon program.
-
What exactly is an "HSL Color Rotation" then ?
If you have a green icon image selected and you want to do a color rotation you must have three components. First the image to modify. Second choose a source color from the image. Third choose a reference color from the HSL ColorWheel as you see in the attachment.
If our source color is a shade of green and we select golden orange as our reference color the program will convert each pixel to HSL then add the Rotation Value in degrees to rotate each pixel around the wheel. The result looks amazing!!
Changing the "color theme" of icon images is especially useful in making new icons or new iconsets from an original set. If you have blue drawer icons and you want a nice set of green or purple icons, just do hsl color rotations. Sounds easy enough. :)
-
This is a sample of HSL Hue Rotation.
The source color group is light brown. The reference color group is light blue.
ALL pixels in the image including the background are rotated by adding the rotation value to each. You see the result.
To mitigate changing backround colors masks can be used. In addition to masking individual colors such as white, black, shades of grey can be skipped, or selectively filtered out. In our case we can filter out the white and yellow in glow borders so they won't be processed in the hsl hue rotation.
-
Hmmm. I kinda like the chocolate brown drawer icon. :)
This is what is possible with HSL Color Rotation. It's a color rotation because I now realize we must adjust Saturation and Luminance as well as Hue to get the desired effect. The original icon was a plum purple from Amiga OS 3.5 days gone by.
The same type of color rotation is possible with Dual-PNG. :)
For the processing I rotated the hue 80 degrees and adjusted saturation to 50% and luminance -10. I will continue to experiment and to incorporate these cool functions in IconEdit.
-
One day I was working with the Amiga Clown. You may know him. :)
I was trying to get the right colormap for an ilbm. But all I had for reference was a png PLTE chunk. So natural I used a hex editor and copied the color values. BUT I forgot that png puts the chunksize before or after the chunkid, but ilbm was different.
So my ilbm colormap was 4 bytes off...imagine my horror and surprise when the clown turned GREEN.
I am indeed familiar with the Amiga clown-face.... judging on my own story with it, it could have been my personal face ;D
For some reason i made 2 mistakes at once. One being the fact that i didn't took endianess into account properly and my code was off by one byte. At the time i truly wondered if the clown had been drinking a bit too much alcohol because his nose was a bit blue :P
It's almost like you know what I'm thinking. :)
Nah... we are just both stupid in the same way ;D
Yes. I intend to use ReadRGBPixel and compare output to ReadPixel.
You'll be amazed of the outcome... ah well, seeing your follow-up post, you did manage to conclude that on your own ;)
Of course, the HSL Colorwheel I refer to is different than a color requester.
True, indeed.
I suppose the interesting question is: Can I use HSL Color Rotation on an ILBM image then save it as ILBM ? Yes. Because it is an indexed image. And we only need to change the rgb colormap values. That would be super exciting! :)
Sure you can. It is a bit different to implement than your average rgb color-shifting but it should be do-able.
With Free Pascal i can load the image in a special 16 bit per colorgun format (so 64 bits per pixel if you include alpha channel) and to any translation or filtering. That offers more than enough fire-power to do some precision color-shifting.
-
Poor kitten, turning up all blue :D
Hmmm. I kinda like the chocolate brown drawer icon. :)
that color should go well with some vanilla ice-cream ;)
This is what is possible with HSL Color Rotation. It's a color rotation because I now realize we must adjust Saturation and Luminance as well as Hue to get the desired effect.
ah..... yes, indeed there are other things that make color rotation work a bit better :-)
For the processing I rotated the hue 80 degrees and adjusted saturation to 50% and luminance -10. I will continue to experiment and to incorporate these cool functions in IconEdit.
Thank you for the progress report and thank you for adding that to the icon-editor. It is a welcome addition that one can play with.
Congratulations on yet another great job !
-
magorium
Although HSL Color Rotation is nice for producing Glow Icons...
-
magorium
It's even nicer with 32bit Dual-PNG Icons...
And Icon Alias would make replacing these drawers easier with new iconsets. 8)
Better yet when I introduce the Wu Algorithm in IconEdit to produce Hybrid Icons from PNG like ILBM2ICON does the 8bit Glow Icons will be nearly flawless even on AROS 68k. ;D
-
miker1264 it would be useful and exceptional if in system startup you could change the color of all the icons of the system, in order to adapt them to the theme :)
-
miker1264 it would be useful and exceptional if in system startup you could change the color of all the icons of the system, in order to adapt them to the theme :)
That's what Icon Alias does. :)
-
If I understand well we will have a tool that never existed in the world AMIGA and AMiGA NG ;)
-
If I understand well we will have a tool that never existed in the world AMIGA and AMiGA NG ;)
Kalamatee came up with the concept of Icon Alias so he deserves credit for that. I have been experimenting with it in Icon Library and I'm very excited about the possibilities. :)
In the last few days I introduced AROS to HSL Color Rotation. That's another thing Amiga didn't have. But it works well so far. Color Quantizing using the Wu Algorithm is something else Amiga didn't have. It didn't need it when everything was 8 bitplanes or less. The color reduction techniques found in mamy Amiga programs are inefficient.
-
Thanks miker, I'll gladly try these apps with the new AROS One icons
-
For the IconEdit program I'm working on, I had a dilemma as far as the graphics.
The legacy icon support is based on modifyicon. It uses classic methods to read the icon data and it uses Graphics Library to draw the background and images which is a very slow method.
So in order to add support for png icons and argb data chunks from hybrid icons I needed a new method. First I tried using Icon Library functions to load png images but there were problems.
I needed a unified display method for legacy and for png icons. While messing with code from Icon Library I found ReadMemPNG and LoadIconPNG that had a method to find offsets for both images...then I had an idea.
Use datatype objects for ndto (normal) and sdto (selected). That works for glow icons and png icons. I'm already using datatypes to save images and getting a bitmap to display is then easier.
I can use the offsets to read data into a byte array then set up a datatype for both images to copy the data into.
I think that's an elegant solution to use picture datatypes! 😊
-
Here is a design concept for the HSL Color Rotate User Interface. On the left is Before and on the right is After. It's designed for simplicity but also to allow a preview of the color transformation before applying the color rotation. There will still be one last chance in the main program to change your mind before saving the new colorful icon. :)
-
Miker, that's amazing.
Will be there a cli interface for it, so i can replicate the same color rotation to all icon files with a command within a script?
-
Miker, that's amazing.
Will be there a cli interface for it, so i can replicate the same color rotation to all icon files with a command within a script?
That would be a nice feature. That is possible. :)
As a novelty or for your own satisfaction using cli for hsl color rotation or any color transformation is possible but it only works with default drawer icons. Any drawer icons with small graphic attached require a mask.Much like assembling IcarosDesktop assembling colored icons involves much manual effort.
There is a better way using pre-made sets of colored drawer icons in an iconset directory. Simply use a cli icon exchange utility to replace the original icon with the corresponding alternate colored icon. Do that in sequence for each drawer.
I can work with you on the procedure. Do you like the new colored icons? I'm assembling complete sets of colored drawer icons in several ice cream flavors. No more "plain vanilla" Icaros icons! Now we have more colors. 8)
-
Miker, that's amazing.
Will be there a cli interface for it, so i can replicate the same color rotation to all icon files with a command within a script?
That would be a nice feature. That is possible. :)
As a novelty or for your own satisfaction using cli for hsl color rotation or any color transformation is possible but it only works with default drawer icons. Any drawer icons with small graphic attached require a mask.Much like assembling IcarosDesktop assembling colored icons involves much manual effort.
There is a better way using pre-made sets of colored drawer icons in an iconset directory. Simply use a cli icon exchange utility to replace the original icon with the corresponding alternate colored icon. Do that in sequence for each drawer.
I can work with you on the procedure. Do you like the new colored icons? I'm assembling complete sets of colored drawer icons in several ice cream flavors. No more "plain vanilla" Icaros icons! Now we have more colors. 8)
yes, I really like 'em!
-
Here are some more and a sneek peek at the processing involved.
As a test for my copy mask function in ShowPicture I selected three sets of colored drawer icons. The beauty of copy mask is that I can use the base drawer images for each color as the start point and simply make mask templates and copy the small graphic for each icon image.
Here's how it works. From the original MyWorkspace Icon I split the icon into two images, MyWorkspace 1.png and MyWorkspace 2.png. I then paint a white pixel mask for each of the two images. You can see the mask templates, the original images and the three sets of base colored images in the screenshot.
I copy the MyWorkspace 1_mask.png to Ram Disk: and rename it "mask.png". Then I open the original MyWorkspace 1.png for comparison. From the Masking Menu I select Copy Mask and a file requester asks for a destination image. Select any of the first images from blue, green or brown sets. Applying the mask is automatic and the pictures changes to the new colored image.
Then we can save the newly processed image and move to the next colored base image using the same mask. The process is the same for the second image in each set. We start by loading the mask and the original then select destination. Using the master templates for each icon make processing faster but it's very repetitive and tedious work. "Some assembly required".
The programming involved uses three sets of byte arrays. It looks at each pixel in the mask. Is it White? If so, compare to the original pixel. If it is also White, skip it and go to the next pixel. It's just a White Pixel. But if the original is NOT White, copy the original pixel to the destination byte array for the image we selected with the file selector from available colored icons. The resulting image is beautiful as you can see.
Now you can see the resulting Colored MyWorkspace images ready for Icon Assembly. :)
-
wow!
-
Wow! Yes. It's an involved process to make beautiful icons!
I will process each drawer separately because there are many drawer icons in each. First I will make new colored icons for "System" then other drawers will follow. In System there are about 14 or so drawer icons. It seems easy enough, right?
First part of the process is to split the icons. I spent about 2 hours last night splitting them into png files. I need a batch process for that. Today I spent about an hour making 28 mask templates, one for each image. It should take another hour to make the new colored icons from the mask templates. But the master templates can be re-used to make unlimited colored drawer icons, in theory. Splitting the icons and making mask templates is the most time consuming part of the process.
IconInject is supposed to be an icon exchange utility but for some reason it doesn't work on 64bit. I'll try it on 32bit. If it doesn't work I can make another little utility. It really only needs to do some fancy juggling. Split the source and dest icons into images and export the "icOn" chunk and copy it to the source, then re-assemble and rename the images into a new icon. ;)
No worries! It all makes sense to me in a mathematical and procedural way. The author of the original set, Mr Ken, probably used Alpha Image Compositing with Alpha Blending. Nice! :)
Here is attached the Copy_Mask Function that makes beautiful icon images if anyone is interested.
Once I write a new function for Icon Alias in Icon Library to display a drawer full of alternate icons from an IconList then I can demonstrate what IcarosDesktop looks like with new icons.
-
There is a saying "necessity is the mother of invention".
So now we have a working Batch Process for making Colored Drawer Icons. It's a beautiful thing! :)
But sometimes inventions happen by accident, or at least their use was not intended.
Recently I made several sets of Colored Drawer Base Images which are for drawer1 and drawer2. I didn't use mask templates so even the glow border was transformed during HSL Color Rotation.
Using the New Batch Processing I made a set of icon images and icons. When I processed the Orange Icons I found something interesting and possibly very useful.
I noticed I had forgotten to fix the Glow Border. In every icon it was a very pleasant Neon Blue! What a dramatic effect.
Blue on blue, green on green, or yellow on yellow or even brown wouldn't be dramatic. But what about Neon Blue or Neon Green Glow Borders with Charcoal Black Icons? Or Red Icons with Neon Blue Borders? I only need change the border on one Base Image (drawer2.png) then all resulting icons have blue borders.
Custom Neon Glow Borders with Your New Colored Icons??