Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Converting 24-Bit images to Paletted Images (2-colors to 256-colors)
#1
After nearly eight years (2018) on the run (away from the QB64 project) and shutting down my popular QB64 forum, I'm opening up another one. Actually, the site that will host my new QB64 forum, will also host other forums for other programming languages, except C++. That is on another domain name.

In saying this, you can't have a QB64 forum without new and exciting QB64 projects.

Here's a project I thought I would use to wet some whistles...

   

Converting 24-Bit images into a 2- to 256-color palette image.

   

   

Here's a comparison screenshot between my demo and Adobe Photoshop 2025:

   

Even at 256-color palette, my demo is closer to the original colors than what Adobe Photoshop produces:

While this appears to be exciting to see, it would be even better if you could get a hold of the source code to the project. Well... Here it is, along with the images used:

On a side note, press any key to increase the number of palette colors.


.zip   RGBtoPalette.zip (Size: 1.85 MB / Downloads: 41)
The Joyful Programmer has changed call signs. The Joyful Programmer is now called "AstroCosmic Systems".
Reply
#2
You need to catch up with QB64PE's capabilities.  Here's  all it takes  to  toggle from 32-bit to  256 colors:


Code: (Select All)
Screen _NewImage(800, 600, 32)
nature = _LoadImage("nature.jpg", 32)
nature256 = _LoadImage("nature.jpg", 256)
nature256a = _LoadImage("nature.jpg", 257)

Do
    Cls , 0
    k = _KeyHit
    Select Case k
        Case 27: System 'escape to end
        Case 19712, 18432: Color32 = Color32 + 1 'right/up
        Case 19200, 20480: Color32 = Color32 - 1 'left/down
    End Select
    If Color32 < 0 Then Color32 = 2
    If Color32 > 2 Then Color32 = 0
    Select Case Color32
        Case 0: _PutImage , nature: Print "32-bit"
        Case 1: _PutImage , nature256: Print "256-color QB64 set  palette"
        Case 2: _PutImage , nature256a: Print "256-color adaptive palette"
    End Select
    _Limit 30
    _Display
Loop

Save image below as "nature.jpg".


Attached Files Thumbnail(s)
   
Reply
#3
Tongue 
(11-22-2025, 07:27 AM)SMcNeill Wrote: You need to catch up with QB64PE's capabilities.  Here's  all it takes  to  toggle from 32-bit to  256 colors:


Code: (Select All)
Screen _NewImage(800, 600, 32)
nature = _LoadImage("nature.jpg", 32)
nature256 = _LoadImage("nature.jpg", 256)
nature256a = _LoadImage("nature.jpg", 257)

Do
    Cls , 0
    k = _KeyHit
    Select Case k
        Case 27: System 'escape to end
        Case 19712, 18432: Color32 = Color32 + 1 'right/up
        Case 19200, 20480: Color32 = Color32 - 1 'left/down
    End Select
    If Color32 < 0 Then Color32 = 2
    If Color32 > 2 Then Color32 = 0
    Select Case Color32
        Case 0: _PutImage , nature: Print "32-bit"
        Case 1: _PutImage , nature256: Print "256-color QB64 set  palette"
        Case 2: _PutImage , nature256a: Print "256-color adaptive palette"
    End Select
    _Limit 30
    _Display
Loop

Save image below as "nature.jpg".

    Steve, this is a great capability in the language libraries.
    It's very convenient for games and also for prototyping
    more advanced Image processing !

    There are still reasons to roll your own code here.

    I get much better 8 bit images by allowing ImageMagick to do the palette mapping and dithering and then setting 
    The 8 bit image palette with _palettecolor.  for the Image Handle.

    The QB64 set color palette actually kinda sucks  Smile
Reply
#4
@ahenry3068 Notice that we have two modes you can choose from for default.
256 uses the QB64PE built in palette.
257 does as you suggest and uses an adaptive palette for whatever best suits the image itself.

You can see the difference with the demo code above.

The main advantage to using the 256 color code is you *know* what each color is in your palette. Such as COLOR 40 is bright red. With an adaptive palette, the colors are whatever is best for the image, but not set to our existing scheme, so you may not be displaying the colors you expect with any text or whatnot which you use with that image.
Reply
#5
(11-22-2025, 05:42 PM)SMcNeill Wrote: @ahenry3068 Notice that we have two modes you  can choose from for default.
256 uses the QB64PE  built in palette.
257  does as you suggest and uses an adaptive palette for whatever best suits the image itself.

You can see the difference with the  demo code above.

The main advantage to using the 256 color code is you *know* what each color is in your palette.  Such as COLOR 40  is bright red.  With an adaptive palette,  the colors are whatever is best for the image, but not set to our existing scheme, so you may not be displaying the colors  you expect with any text or whatnot which you use with that image.
   I get all this Steve.  Thank ya.   But I still think ImageMagick does a better job than the builtin Adaptive palette.  (which isn't actually bad !) 

   Another reason to roll your own routine would be to map a whole bunch of images to an existing palette when porting from another platform too !

   Probably the built in options cover a lot of use cases.   But there are still reasons to *Roll your own code here !*
Reply
#6
(11-22-2025, 07:27 AM)SMcNeill Wrote: You need to catch up with QB64PE's capabilities.  Here's  all it takes  to  toggle from 32-bit to  256 colors:
I saw the 256-color index _LOADIMAGE statement awhile back and tried it. I was curious to see what it looked like and tried it, but I was not impressed at all with it.

Here's a side-by-side comparison between the output of my demo vs mode 256:

   

This image mode, 256, in QB64pe's _LOADIMAGE, has low-level details, and the dithering is patterned, making it hard on the eyes. But, I assume this is by design as it is primarily used to load images that were originally drawn in QB64's master palette, which should be the color palette from VGA's 256-color palette screen modes.

Next is another screenshot, similar to the screenshot above, but for mode 257:

   

It's obvious what I shared here provides a way better conversion and dithering pattern, but also goes further than what QB64pe offers, by having the ability to convert full-color image to a 2-color palette, all the way up to 256-color palette. It also uses a perceptual palette, which is better for pictures and photos. but that aspect is neither here or there as adaptive colors has it's own usefulness, where perceptual will fail.

In saying all of this, this demo is not about one type of color system. It demonstrates and shows how to do one way of converting full-color images to palette images, and one way of dithering. There are many options for both in existence, and each have their usefulness. I'm sharing the source code to the project for others to enjoy and use in their projects if they so choose. The systems can even be implemented into QB64pe if you so choose.

This project was done in QB64pe for quick setup and testing, and to share with those in this community, the one I am working on, and other communities and people that use QB64. However, once all the core fundamentals are working, it all will be converted to shaders and used with my Vulkan projects, such as the sphere of rotating cubes I shared in the private "Freedom to Speak" sub forum on this forum.

Now that the 256-color palette conversion system is working, there are other conversion and dithering systems that looked intriguing and way better, but much more complex to implement. If they look like the better option, the next step is to do something that hasn't been done before. That is to up the palette system to 65'536-colors. This is all part of my "major project" that I have been working on for some years now, though better computer hardware was needed before the proper tools could be used, and a lot of learning was needed to be done. Thankfully, all of that has been accomplished and the wheels are spinning faster and faster.


(11-22-2025, 06:51 PM)ahenry3068 Wrote:    Another reason to roll your own routine would be to map a whole bunch of images to an existing palette when porting from another platform too !
Ooh... You hit on topic which are in my notes to do! Too funny! The "major project" (called this to keep the peace and not raise Steve's blood pressure anymore than it is) I mentioned focuses on palette screen modes and graphics as well. I always enjoyed palette screen modes and graphics, as well as pixelated graphics and games. This demo is part of that system, at least in concept.


(11-22-2025, 06:51 PM)ahenry3068 Wrote:    Probably the built in options cover a lot of use cases.   But there are still reasons to *Roll your own code here !*
The built-in options do cover some use cases, but not all. I personally wouldn't use those built-in options as I never use the colors in the VGA 256-color palette for anything, outside of the first 16-colors. There's no need since they can be changed in QB64 as well as on the actual hardware for those real hardware screen modes, which sadly you can not access in GUI operating systems like Windows.

Some reasons for rolling your own code are to learn how to do things yourself, create your own system to suite your own needs, or to create better systems, just to name a few. Of course, all three of those reasons are why I am creating these things.
The Joyful Programmer has changed call signs. The Joyful Programmer is now called "AstroCosmic Systems".
Reply
#7
[quote pid="37497" dateline="1763860804"]
(11-22-2025, 06:51 PM)ahenry3068 Wrote:    Another reason to roll your own routine would be to map a whole bunch of images to an existing palette when porting from another platform too !
Ooh... You hit on topic which are in my notes to do! Too funny! The "major project" (called this to keep the peace and not raise Steve's blood pressure anymore than it is) I mentioned focuses on palette screen modes and graphics as well. I always enjoyed palette screen modes and graphics, as well as pixelated graphics and games. This demo is part of that system, at least in concept.


(11-22-2025, 06:51 PM)ahenry3068 Wrote:    Probably the built in options cover a lot of use cases.   But there are still reasons to *Roll your own code here !*
The built-in options do cover some use cases, but not all. I personally wouldn't use those built-in options as I never use the colors in the VGA 256-color palette for anything, outside of the first 16-colors. There's no need since they can be changed in QB64 as well as on the actual hardware for those real hardware screen modes, which sadly you can not access in GUI operating systems like Windows.

Some reasons for rolling your own code are to learn how to do things yourself, create your own system to suite your own needs, or to create better systems, just to name a few. Of course, all three of those reasons are why I am creating these things.
[/quote]

   I actually plan on giving your code a pretty deep dive.   It has the potential to replace my Shell out to ImageMagick in this project: https://qb64phoenix.com/forum/showthread.php?tid=3929 You might find this interesting, it creates Videos for the Commander X16 platform from mp4 or other. They can be 8 bpp, 4 bpp 2 bpp or even 1bpp frames. There is also a 64 bit player for the X16 format in QB64PE
Reply
#8
[quote pid="37499" dateline="1763865489"]
   I actually plan on giving your code a pretty deep dive.   It has the potential to replace my Shell out to ImageMagick in this project: https://qb64phoenix.com/forum/showthread.php?tid=3929    You might find this interesting, it creates Videos for the Commander X16 platform from mp4 or other.    They can be 8 bpp, 4 bpp 2 bpp or even 1bpp frames.  There is also a 64 bit player for the X16 format in QB64PE
[/quote]

Wow! It's been nearly a month since I visited here! I've been very busy lately with five websites (one for my current brand [AstroCosmic Systems (tm)], one for my other brand [my nickname here], one for my major project [last website that will be worked on], on for C++ programming, and one for programming in general [mostly BASIC programming]) and my "major project". Plus, I live on Discord, where I chat with friends and qb64'ers-exhilees (such as myself - been with the community between 2009-2018 - I'm surprised Steve lets me stay here).

I'm glad to hear that this could be a potential library for your projects. Please use it however you want, anyway you want, and enjoy.

One thing I failed to mention in my previous posts, the original idea for doing this on the GPU is for reproducing the color modes of the CGA, EGA, and VGA screens (i.e. screen modes 1-13), though not necessarily the static resolutions. Then my creative juices started flowing, thinking about how cool it would be to provide the capability of having any size screen palette size. To take that one step further, the developer can easily change the number of palette colors available for the current screen in real time without having to close the current screen and open another one, like you would in QB64, or even with OpenGL and Vulkan graphic libraries. This would make all kinds of cool and amazing graphic demos, games, and apps. Think of a game that starts out in 2-colors, even a 3D game, and a color is added after specific points or challenges are complete, until you hit a full full-color game.

On a side note, I have moved away from the GCC compiler toolchain, which I have used since 2012, for multiple reasons. For one, it's a monolithic project and not really practical to use for my project. Instead, I moved over to LLVM-CLANG. I used to call it just CLANG, but I learned CLANG itself is simply a front-end built on top of the LLVM project. This is the path I am no taking. Making my own front-end.
The Joyful Programmer has changed call signs. The Joyful Programmer is now called "AstroCosmic Systems".
Reply
#9
(12-20-2025, 07:45 AM)The Joyful Programmer Wrote: [quote pid="37499" dateline="1763865489"]
   I actually plan on giving your code a pretty deep dive.   It has the potential to replace my Shell out to ImageMagick in this project: https://qb64phoenix.com/forum/showthread.php?tid=3929    You might find this interesting, it creates Videos for the Commander X16 platform from mp4 or other.    They can be 8 bpp, 4 bpp 2 bpp or even 1bpp frames.  There is also a 64 bit player for the X16 format in QB64PE

Quote:Wow! It's been nearly a month since I visited here! I've been very busy lately with five websites (one for my current brand [AstroCosmic Systems (tm)], one for my other brand [my nickname here], one for my major project [last website that will be worked on], on for C++ programming, and one for programming in general [mostly BASIC programming]) and my "major project". Plus, I live on Discord, where I chat with friends and qb64'ers-exhilees (such as myself - been with the community between 2009-2018 - I'm surprised Steve lets me stay here).

I'm glad to hear that this could be a potential library for your projects. Please use it however you want, anyway you want, and enjoy.

One thing I failed to mention in my previous posts, the original idea for doing this on the GPU is for reproducing the color modes of the CGA, EGA, and VGA screens (i.e. screen modes 1-13), though not necessarily the static resolutions. Then my creative juices started flowing, thinking about how cool it would be to provide the capability of having any size screen palette size. To take that one step further, the developer can easily change the number of palette colors available for the current screen in real time without having to close the current screen and open another one, like you would in QB64, or even with OpenGL and Vulkan graphic libraries. This would make all kinds of cool and amazing graphic demos, games, and apps. Think of a game that starts out in 2-colors, even a 3D game, and a color is added after specific points or challenges are complete, until you hit a full full-color game.

On a side note, I have moved away from the GCC compiler toolchain, which I have used since 2012, for multiple reasons. For one, it's a monolithic project and not really practical to use for my project. Instead, I moved over to LLVM-CLANG. I used to call it just CLANG, but I learned CLANG itself is simply a front-end built on top of the LLVM project. This is the path I am no taking. Making my own front-end.
       I did give your code the deep dive I promised.    I ended up not using it as a complete replacement for my ImageMagick SHELL,    However I did bring in a couple of your routines to let me implement a capability I didn't have before.   

       The Commander X16 only has palettized graphics.   It doesn't have any 24 bit modes.   It only has 1 palette.   (Though 4 bit sprites or tiles can actually be mapped to any 1 of 16 palette rows)   But it makes it problematic to mix Images on Screens for different Palette's

        My MovieMaker Video format is actually several sub-formats with most of those carrying optimized palette Data for every single frame of the Video.    This actually allows 8 bit Videos to look surprisingly good and is the best mode for full screen Videos.

         That is a problem though if I want to display a Small Video on the screen with say a larger Bitmap background.   To do this reasonably all the on screen graphics need to share a palette.
I've have been somewhat stymied in this goal by ImageMagicks refusal to maintain Palette order when mapping an Image to an External palette !    (It seems the Authors have neglected this capability !)     

     I had a glimmer of a solution already.   Execute the ImageMagick command then restore the correct Palette order in my own code.   The means to do this efficiently hadn't presented itself to me yet.    But the Map Color function in your code gave me almost a turn key function to implement this capability.     I didn't lift it verbatim, It needed a little modification to fit into my code base,  but it was a whole bunch quicker in this case to adapt your function rather than rolling my own !     Thank you for this.     The capability to create 4 bit & 8 bit sprite based Videos with a single Static palette now exists in my development code base and will be in the next release of my project.     I even added the capability to Map a Video to the Commander X16 system Default Palette (*which is more balanced than the default 13h VGA Palette*) this allows simplified playback coding for using my Videos in other Commander X16 applications !

Thanks Again,
Tony
Reply
#10
Tony,

I am very thrilled that you were able to use parts of what was offered, even if you needed to modify them for your own purposes. That is what FLOSS (Free/Libre Open-Source Software) products are all about!

I already assumed people would have to "hack" up the code and use only the parts they needed, since the entire source was written for a specific solution, not all solutions, so it wouldn't make since to try and use all the source code in other projects. This is also true for when I translate the algorithm parts from QB64 to GLSL (OpenGL Shading Language) to run on the GPU. Some of the code will run in the fragment shader, while others will run in the compute shader.

Why do stuff on the GPU (the processor on your video card) instead of the CPU? The answer in one simple words is: Cores. General processor cores on CPUs from the past decade to today can have 2-, 4-, 8-, and even 16-cores, while higher end processors, like the Intel Sierra Fores, can have to 288 cores. That's a lot of threads to have when doing multiple things at the same exact time. However, GPUs can have way more than that. For example, the GeForce RTX 5090 has 21,760 (CUDA) cores. This can make computing on the video card's GPU way faster than doing it on the local CPU, if you code them correctly. Coding on a GPU is not linear like it is on the CPU, so coding for involves learning a style of coding. For me, it's almost like going from a linear coding style, like you get in QB64, or even C++ on the console, to event-driven coding, like regular Window apps.

The shared demo picks the best colors from the full-color image to create the palette, but the idea for my major project is to pick the colors in the fixed palette that are closest to those in the full-color image.

On a side note, I am thrilled to find others who enjoy watching "The 8-Bit guy" on YouTube, as I do. Here's the YouTube videos where David Murray discusses his dream computer, the X16:

Building my dream computer - Part 1
Building my Dream Computer - Part 2

I love the Commodore 64/128, as well as the Apple ][ line of computers. I grew with them, and those are the main two computers I learned a lot about coding.

Do you have a website, or a place where you share your project at? I would love to check it out.


Thank you for your inspirations and creativity!

Walter W. Whitman
The Joyful Programmer
AstroCosmic Systems (tm)
The Joyful Programmer has changed call signs. The Joyful Programmer is now called "AstroCosmic Systems".
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Bright Circle Colors SierraKen 4 622 08-23-2025, 03:33 PM
Last Post: DANILIN
  A little bit of spark fun today TerryRitchie 2 839 05-18-2024, 12:59 AM
Last Post: bobalooie
  _ROL & _ROR A quickie bit of crypto OldMoses 0 520 09-05-2022, 09:36 PM
Last Post: OldMoses
  Load Image 256 Petr 1 752 05-22-2022, 06:19 PM
Last Post: Dav
Video QB64 Win32 Video Player (64 bit) SpriggsySpriggs 6 1,525 04-24-2022, 05:33 PM
Last Post: Dav

Forum Jump:


Users browsing this thread: 1 Guest(s)