News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Has anyone used gdiplus to change hue?

Started by zedd151, April 11, 2025, 08:15:16 AM

Previous topic - Next topic

zedd151

I was wondering if anyone here has any experience with changing the hue of an image using gdiplus.

My idea is instead of using several different colored .pngs, I was thinking, "why not use only one .png image and just change the hue to any color the user chooses?"  The user then can change the color of all of the graphic elements, if I can figure out a way to implement it.

Any ideas where to start? What exactly should I research?

NoCforMe

Welll, if you can somehow get the image as just a raw bitmap (NOT a .BMP), and you know
  • the image width & height
  • the image bitness (# bits/pixel)
then you could cruise through the bitmap and change colors.
Somehow. That might not be easy. But you could probably figure out how to change red (or reddish) pixels to blue or blueish.
Assembly language programming should be fun. That's why I do it.

zedd151

Quote from: NoCforMe on April 11, 2025, 08:39:25 AMWelll, if you can somehow get the image as just a raw bitmap (NOT a .BMP), and you know
  • the image width & height
  • the image bitness (# bits/pixel)
then you could cruise through the bitmap and change colors.
Somehow. That might not be easy. But you could probably figure out how to change red (or reddish) pixels to blue or blueish.
It's not that easy. The images are not single color, plus they have an alpha channel. Hence the need for gdiplus. Otherwise I'd just plunk a new color on the colormap in pace of the old color. (For 1, 4, 16, or 256 color bitmaps that is.) That's easy.

If you can demonstrate your idea, I'll try it.  :smiley:  I guess you could swap the R G and B? Or somehow perform voodoo on them.

NoCforMe

Quote from: zedd151 on April 11, 2025, 08:43:08 AMIt's not that easy. The images are not single color
I would assume not.
Quoteplus they have an alpha channel. Hence the need for gdiplus.
Not necessarily; the alpha channel is just the 4th byte, otherwise unused, of the RGB color.
You can simply leave that data alone to preserve the transparency of those pixels.
QuoteOtherwise I'd just plunk a new color on the colormap in pace of the old color. (For 1, 4, 16, or 256 color bitmaps that is.) That's easy.
Yes; I've done that in my BMP toolbar creator, where I created a new palette (what you called the "colormap") to combine several images into one with a common palette.
But that wouldn't be the way to do it, I don't think. What I was doing was preserving the colors of the component images (more or less) and combining them into a single image with a single palette.
QuoteIf you can demonstrate your idea, I'll try it.  :smiley:  I guess you could swap the R G and B? Or somehow perform voodoo on them.
Not swap; that would give really weird results.
More the second choice: voodoo.

Let's say you have an image that's predominantly one color, say red: not a single color, but the image is mainly red or reddish.
You could identify those pixels (say by selecting those with a minimum R value) and change them to blue or blue-ish, by increasing B and decreasing R.
Still not easy, but probably do-able.

What I don't know how to do is getting the raw bitmap pixels from a GDI+-loaded image.
Anyone know the magic incantation to do that? If so, I could experiment a bit.
Assembly language programming should be fun. That's why I do it.

zedd151

Sounds like a neat coding exercise, but I'm not up for that kind of challenge.
Probably would be time consuming.

Let me take a look at my png's in Gimp, to see exactly how many colors there are.... brb. I don't think they are 24 bit color...

zedd151

Quote from: zedd151 on April 11, 2025, 09:01:59 AMI don't think they are 24 bit color...
They are 32 bit RGBA. I thought I had reduced the colors. I guess not.

You cannot view this attachment.

PostImage screwed with the image I posted originally. Made it 180x180 and 43 kb.
The one above is original size 80x80 and ~9kb. You can right click it and "Save image as..." if you want to experiment with it.

NoCforMe

I found a way to get access to the pixels:
GdipBitmapGetPixel()
Not the best way (probly slow), but all you need is the (x,y) coords. of the pixel.
And of course there's a GdipBitmapSetPixel() as well.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: zedd151 on April 11, 2025, 09:01:59 AMSounds like a neat coding exercise, but I'm not up for that kind of challenge.
Don't give up so easily. It could boil down to something like this:
loop through all pixels (x,y)
for each pixel
    get R
    if R > (some threshold)
          set R low
          set B high
When I get done with (part of) my other 85,792 projects I might play around with this.
Assembly language programming should be fun. That's why I do it.

zedd151

Quote from: NoCforMe on April 11, 2025, 09:16:11 AMI found a way to get access to the pixels:
GdipBitmapGetPixel()
Not the best way (probly slow), but all you need is the (x,y) coords. of the pixel.
And of course there's a GdipBitmapSetPixel() as well.
I don't know about that - it might be a fun experiment, but surely there has to be a better way.

In any case, I don't mind having multiple images, but it would be nice to be able to change the hue 'on-the-fly' without too much acrobatics.

Quote from: NoCforMe on April 11, 2025, 09:19:42 AMWhen I get done with (part of) my other 85,792 projects I might play around with this.
:biggrin:
Yes, always too many things to do. But so little time. Same here.

sinsi

Found this on reddit but it might be a bit too involved :biggrin: (and it's .net :dazzled: )
Quote from: Replacing all pixels of a certain colour with another colour in a bitmapYou can use GDI+ for this, using a DrawAttributes and a ColorMap. basically load the image then create a new blank canvas and use ImageAttributes to draw the loaded image into that new canvas using a ColorMap table.

Load existing image.

Create new Bitmap the same size as the original image.

use Graphics.FromImage() to create a new canvas from the second, new, image.

Create a new ImageAttributes instance, create a array of ColorMap, one for each mapping of old to new colours, presumably from your dictionary. Assign to the ImageAttributes class via .SetRemapTable().

use DrawImage on your second canvas and draw the first image loaded from the file to the canvas using the Image Attributes parameter.

If desired you can now save the replaced bitmap by saving the second bitmap you created.

NoCforMe

I'm sure that would work, but just think how complex that would be:
You'd have to create that "dictionary", which sounds quite non-trivial.
(Unless you could maybe grab someone's already-made dictionary?)
My proposal is to change the image in situ, without having to create a new image from scratch like they do.
Assembly language programming should be fun. That's why I do it.

zedd151

btw, I asked ChatGPT for code for this...
Too many errors in that code.  :tongue:
Like two arguments short on a very important invoke...

it's not totally useless. But usually for the most interesting stuff, it is about as useless as it can get.  :joking:

NoCforMe

Quote from: zedd151 on April 11, 2025, 10:15:11 AMbtw, I asked ChatGPT for code for this...
Too many errors in that code.  :tongue:

it's not totally useless. But usually for the most interesting stuff, it is about as useless as it can get.  :joking:
"Hallucinations 'Я' Us"
Assembly language programming should be fun. That's why I do it.

zedd151

Quote from: NoCforMe on April 11, 2025, 10:28:34 AM"Hallucinations 'Я' Us"
I keep telling you, you gotta lay off of them 'shrooms.  :biggrin:

Like it or not, AI is sometimes useful. No like, no use.

NoCforMe

Me no like, no use.
"Artificial Ignorance"
Assembly language programming should be fun. That's why I do it.