-
replace color in bitmap
Okay, let's say I have a GDI+ Bitmap object. It contains a nice little bitmap picture inside. How can I replace a certain color in the bitmap with another of my choice... let's say for example replace all white with SystemColors.Desktop or something.
How can I do that?
Thanks :)
-
The code below is from a C# object that will take a bitmap and allow you to adjust contrast, brightness, red, green and blue colors as well as make it greyscale or invert all the colors. Im sure the code here can be modified to do what you want if you understand the RGB of the colors you want to modify.
After you have referrenced the dll you then just call the functions passing your bitmap as the parameter to each. It works pretty well for the stuff I needed to do.
Code:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace ImageFilter
{
public class BitmapFilter
{
public static bool Invert(Bitmap b)
{
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
int nWidth = b.Width * 3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < nWidth; ++x )
{
p[0] = (byte)(255-p[0]);
++p;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
public static bool GrayScale(Bitmap b)
{
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
byte red, green, blue;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < b.Width; ++x )
{
blue = p[0];
green = p[1];
red = p[2];
p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
public static bool Brightness(Bitmap b, int nBrightness)
{
if (nBrightness < -255 || nBrightness > 255)
return false;
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
int nVal = 0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
int nWidth = b.Width * 3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < nWidth; ++x )
{
nVal = (int) (p[0] + nBrightness);
if (nVal < 0) nVal = 0;
if (nVal > 255) nVal = 255;
p[0] = (byte)nVal;
++p;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
public static bool Contrast(Bitmap b, sbyte nContrast)
{
if (nContrast < -100) return false;
if (nContrast > 100) return false;
double pixel = 0, contrast = (100.0+nContrast)/100.0;
contrast *= contrast;
int red, green, blue;
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < b.Width; ++x )
{
blue = p[0];
green = p[1];
red = p[2];
pixel = red/255.0;
pixel -= 0.5;
pixel *= contrast;
pixel += 0.5;
pixel *= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p[2] = (byte) pixel;
pixel = green/255.0;
pixel -= 0.5;
pixel *= contrast;
pixel += 0.5;
pixel *= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p[1] = (byte) pixel;
pixel = blue/255.0;
pixel -= 0.5;
pixel *= contrast;
pixel += 0.5;
pixel *= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p[0] = (byte) pixel;
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
public static bool Gamma(Bitmap b, double red, double green, double blue)
{
if (red < .2 || red > 5) return false;
if (green < .2 || green > 5) return false;
if (blue < .2 || blue > 5) return false;
byte [] redGamma = new byte [256];
byte [] greenGamma = new byte [256];
byte [] blueGamma = new byte [256];
for (int i = 0; i< 256; ++i)
{
redGamma[i] = (byte)Math.Min(255, (int)(( 255.0 * Math.Pow(i/255.0, 1.0/red)) + 0.5));
greenGamma[i] = (byte)Math.Min(255, (int)(( 255.0 * Math.Pow(i/255.0, 1.0/green)) + 0.5));
blueGamma[i] = (byte)Math.Min(255, (int)(( 255.0 * Math.Pow(i/255.0, 1.0/blue)) + 0.5));
}
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < b.Width; ++x )
{
p[2] = redGamma[ p[2] ];
p[1] = greenGamma[ p[1] ];
p[0] = blueGamma[ p[0] ];
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
public static bool Color(Bitmap b, int red, int green, int blue)
{
if (red < -255 || red > 255) return false;
if (green < -255 || green > 255) return false;
if (blue < -255 || blue > 255) return false;
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
int nPixel;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < b.Width; ++x )
{
nPixel = p[2] + red;
nPixel = Math.Max(nPixel, 0);
p[2] = (byte)Math.Min(255, nPixel);
nPixel = p[1] + green;
nPixel = Math.Max(nPixel, 0);
p[1] = (byte)Math.Min(255, nPixel);
nPixel = p[0] + blue;
nPixel = Math.Max(nPixel, 0);
p[0] = (byte)Math.Min(255, nPixel);
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
}
}
-
My my my.... where do all these freaky clued up intelligent and smart people come from? Many thanks. :) :D :p
-
One more thing
One more thing though, that has been bugging me.
If I've got a picturebox object, and the picturebox is NOT on a form. It's created dynamically in code, in my own function via 'Dim'. The picturebox is not visible. I create a Graphics object via 'Picturebox.CreateGraphics().' I draw an Image on the graphics object via DrawImage method. Now I have this question:
While I can't see the graphics, is it there? If it's there, how can I then save it to a new bitmap object?