Question

I'm trying to change an image color by using Bitmap.SetPixel method. And I have a problem when using it like this:

Bitmap bmp = new Bitmap(Project1.Properties.Resources.gray_square_button);
int Width = bmp.Width;
int Height = bmp.Height;
Bitmap Nbmp = new Bitmap(bmp);
ColorDialog ColorDialog = new ColorDialog();
ColorDialog.AllowFullOpen = true;
DialogResult result = ColorDialog.ShowDialog();

if (result == DialogResult.OK)
{
    for (int y = 0; y < Height; y++)
    {
        for (int x = 0; x < Width; x++)
        {
            System.Drawing.Color BackColor = ColorDialog.Color;
            System.Drawing.Color p = bmp.GetPixel(x, y);
            int a = BackColor.A;
            int r = BackColor.R;
            int g = BackColor.G;
            int b = BackColor.B;

            Nbmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, r, g, b));
        }
    }
    PictureBox1.Image = Nbmp;
}

It will only draw a square with the color that I choose like in this image:

Note that the image won

But if I use it like this, using a manual color and the original image color references (p insted of BackColor which is the color defined by the ColorDialog):

if (result == DialogResult.OK)
{
    for (int y = 0; y < Height; y++)
    {
        for (int x = 0; x < Width; x++)
        {
            System.Drawing.Color BackColor = ColorDialog.Color;
            System.Drawing.Color p = bmp.GetPixel(x, y);
            int a = p.A;
            int r = p.R;
            int g = p.G;
            int b = p.B;

            Nbmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, r, 0, 0));
        }
    }
    PictureBox1.Image = Nbmp;
}

The color is applied correctly and the image is displayed correctly as well:

Here the color and the image displays correctly.

What i've tried is changing only 1 value of the RGB color. But then if you choose a color the color will not be the one you selected but a different one based on the one that is modified by the Color of the Color Dialog.

int a = p.A;
int r = BackColor.R;
int g = p.G;
int b = p.B;

Why are the ColorDialog RGB values not allowing the image to be displayed correctly but only a colored square?

This is the original image:

Original Image

Was it helpful?

Solution

You're replacing the colour of a "shaded" image with a flat selected colour from a ColorDialog. So basically, you're replacing every pixel, regardless of ARGB, with a single ARGB from the dialog, thus completely overwriting any existing image information. You may as well just draw the image from scratch based on the old image's dimensions, without concern for the original image since it's being completely rewritten.

It sounds like what you are probably intending to do is blend the 2 colours together (the original image + the new colour). There are literally hundreds of ways to do this. One that comes to mind is to create an overlay with 50% transparency and apply it over the original image. You could also set the ARGB to an average:

int a = (BackColor.A + p.A) / 2;
int r = (BackColor.R + p.R) / 2;
int g = (BackColor.G + p.G) / 2;
int b = (BackColor.B + p.B) / 2;

This will give you a feel for how to consider the original colours while changing them versus flat out replacing them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top