GDI+ Bitmaps & Images
FAQ Home
1. How do I draw
my bitmap in a disabled state?
2. How can I programmatically create a bitmap?
3. How can I swap colors in a bitmap or icon?
4. How do I create a new image off a base image with certain
portions of the base image modified, in code?
5. How do I extract a Bitmap from an icon of a specific size?
6. How to draw a shadow for a given transparent image?
7. How to draw a faded image?
8. How do I programmatically load, modify and save a bitmap?
9. How do I draw an image with a gray scale?
10. How do I get the color of a pixel in my bitmap?
11. How do I capture a bitmap of my form?
12. How do I create a new bitmap with a new size based on an
existing bitmap?
13. How do I overlay one bitmap over another?
1 How do I draw my bitmap in a disabled
state?
Use the DrawImageDisabled method of the ControlPaint
class.
2 How can I programmatically create a
bitmap?
private void Form1_Load(object
sender, System.EventArgs e)
{
Bitmap newBmp = new Bitmap(100, 100);
Graphics g = Graphics.FromImage(newBmp);
g.FillRectangle(new SolidBrush(Color.Red), 0, 0, 33, 100);
g.FillRectangle(new SolidBrush(Color.White), 34, 0, 33, 100);
g.FillRectangle(new SolidBrush(Color.Blue), 68, 0, 33, 100);
pictureBox1.Image = newBmp; //pictureBox1 was dropped on the form
}
3 How can I swap colors in a bitmap or icon?
You use ImageAttributes, adding a ColorMap that
swaps the colors. Here is a code snippet.
Bitmap originalBMP = (Bitmap)
Image.FromFile(@"c:\circle.bmp");
//make a copy so original will still be available
Bitmap swappedBMP = new Bitmap(originalBMP);
Graphics g = Graphics.FromImage(swappedBMP);
// Create a color map.
ColorMap[] colorSwapper= new ColorMap[2];
colorSwapper[0] = new ColorMap();
colorSwapper[1] = new ColorMap();
colorSwapper[0].OldColor = Color.Red; //red changes to yellow
colorSwapper[0].NewColor = Color.Yellow;
colorSwapper[1].OldColor = Color.Blue;//blue changes to green
colorSwapper[1].NewColor = Color.Green;
// Create an ImageAttributes object, and call SetRemapTable
ImageAttributes imageAttr = new ImageAttributes();
imageAttr.SetRemapTable(colorSwapper);
//overdraw the bitmap with swapped colors
g.DrawImage(swappedBMP, new Rectangle(0, 0,
swappedBMP.Width, swappedBMP.Height),0, 0, swappedBMP.Width,
swappedBMP.Height, GraphicsUnit.Pixel, imageAttr);
pictureBox1.Image = swappedBMP;
Here is similar code that wraps this technique in a method that swaps a
single color.
protected void
DrawMyBitmap(Graphics gph, Color oldColor, Color newColor, Bitmap baseImage,
Rectangle rect)
{
ImageAttributes imgattr = new ImageAttributes();
ColorMap[] clrmap = new ColorMap[1]{ new ColorMap() };
clrmap[0].OldColor = oldColor;
clrmap[0].NewColor = newColor;
imgattr.SetRemapTable(clrmap);
gph.DrawImage(baseImage,rect,0,0,rect.Width,
rect.Height,GraphicsUnit.Pixel,imgattr);
}
4 How do I create a new image off a base
image with certain portions of the base image modified, in code?
This code depends on the actual bitmap in use. This logic sets a random
rectangular portion in the image to a new color.
public class ImageUtil
{
private Image baseImage;
private void InitBaseImage(Image baseImage)
{
this.baseImage = baseImage.Clone() as Image;
}
private Image ApplyNewColorOnImage(Color newColor)
{
// Create a new bitmap off the base image.
Image newImage = this.baseImage.Clone() as Image;
Bitmap newBitmap = new Bitmap(newImage);
// Set the Color cue pixels to the appropriate color.
// This logic of course, depends on the actual bitmap.
for(int i = 12; i <= 14; i++)
for(int j = 2; j <= 14; j++)
newBitmap.SetPixel(j, i, newColor);
return newImage;
}
}
5 How do I extract a Bitmap from an icon of
a specific size?
Icon icoClose;
// Initialize this icoClose from the resource (for example). Code
omitted.
// Now create a new icon off this base icon with the required size (18
X 18) in this case.
Icon icoClose18By18 = new Icon(icoClose, 18, 18);
// Create a bitmap off this icon.
Bitmap bmpClose = icoClose.ToBitmap();
6 How to draw a shadow for a given
transparent image?
The following method will draw a shadow of the supplied image at the
specifed location.
The general usage pattern is to call this method first to draw a shadow at a
(2,2) offset from where the original image will be drawn and then draw the
original image itself.
public static void
DrawShadow(Graphics g, Image iconImage, int left, int top)
{
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
cm.Matrix00 = 0;
cm.Matrix11 = 0;
cm.Matrix22 = 0;
cm.Matrix33 = 0.25f;
ia.SetColorMatrix(cm);
g.DrawImage(iconImage, new Rectangle(left, top, iconImage.Width,
iconImage.Height), 0, 0, iconImage.Width, iconImage.Height,
GraphicsUnit.Pixel, ia);
}
7 How to draw a faded image?
The trick is to use an alpha component while drawing the image.
// transparancy should be in the
range 0 to 1
protected void DrawScrollImage(Graphics g, Rectangle rect, Image image,
float transparancy)
{
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
cm.Matrix00 = 1;
cm.Matrix11 = 1;
cm.Matrix22 = 1;
cm.Matrix33 = transparancy;
ia.SetColorMatrix(cm);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height,
GraphicsUnit.Pixel, ia);
}
8 How do I programmatically load, modify and
save a bitmap?
Below are VB code snippets showing how you might do these tasks.
'load a bitmap from an embedded
resource
Dim Bmp As Bitmap
' from an embbedded resource
Dim curName As String = "BitmapVB.sync.bmp"
Dim strm As System.IO.Stream =
Me.GetType().Assembly.GetManifestResourceStream(curName)
Bmp = New Bitmap(strm)
PictureBox1.Image = Bmp
.....
.....
'load a bitmap from a file
Dim Bmp As Bitmap = Image.FromFile("c:\sync.bmp")
PictureBox1.Image = Bmp
.....
.....
'modify a bitmap
Dim Bmp As Bitmap = PictureBox1.Image.Clone
Dim g As Graphics = Graphics.FromImage(Bmp)
Dim brush1 As SolidBrush = New SolidBrush(Color.Red)
g.DrawString(TextBox1.Text, TextBox1.Font, brush1, 10, 10)
PictureBox2.Image = Bmp
g.Dispose()
....
....
'save a bitmap as a file
Dim dlg As SaveFileDialog = New SaveFileDialog()
dlg.Title = "Save BMP file"
dlg.InitialDirectory = "c:\"
dlg.Filter = "bmp files (*.bmp)|*.bmp|All files (*.*)|*.*"
If dlg.ShowDialog = DialogResult.OK Then
PictureBox2.Image.Save(dlg.FileName
End If
9 How do I draw an image with a gray scale?
Here is some code:
// Not the closest grayscale
representation in the RGB space, but
// pretty close.
// Closest would be the cubic root of the product of the RGB colors,
// but that cannot be represented in a ColorMatrix.
public void DrawGrayedImage(Graphics g, Image image, int left,
int top)
{
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
// 1/3 on the top 3 rows and 3 columns
cm.Matrix00 = 1/3f;
cm.Matrix01 = 1/3f;
cm.Matrix02 = 1/3f;
cm.Matrix10 = 1/3f;
cm.Matrix11 = 1/3f;
cm.Matrix12 = 1/3f;
cm.Matrix20 = 1/3f;
cm.Matrix21 = 1/3f;
cm.Matrix22 = 1/3f;
ia.SetColorMatrix(cm);
g.DrawImage(image, new Rectangle(left, top, image.Width,
image.Height), 0, 0, image.Width, image.Height,
GraphicsUnit.Pixel, ia);
}
10 How do I get the color of a pixel in my
bitmap?
Use the Bitmap.GetPixel method.
[C#]
Color c = myBitmap.GetPixel( xPos, yPos);
[VB.NET]
Dim c as Color = myBitmap.GetPixel( xPos, yPos)
11 How do I capture a bitmap of my form?
You can import the BitBlt API to handle this problem. Here is
a solution offered by Simon Murrell and Lion Shi in the
microsoft.public.dotnet.windows.forms newsgroup. The number used below,
13369376, is Int32 SRCCOPY = 0xCC0020;
You can use Gdi32 dll. You can define the BitBlt method found within the
Gdi32 dll with the code below.
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
ntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
);
And you can then use the copy below in a button click event to save the form
to an image.
Graphics g1 =
this.CreateGraphics();
Image MyImage = new Bitmap(this.ClientRectangle.Width,
this.ClientRectangle.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
IntPtr dc1 = g1.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, this.ClientRectangle.Width,
this.ClientRectangle.Height, dc1, 0, 0, 13369376);
g1.ReleaseHdc(dc1);
g2.ReleaseHdc(dc2);
MyImage.Save(@"c:\Captured.bmp", ImageFormat.Bmp);
You will need to use the System.Drawing.Imaging namespace.
Here is VB code posted by Armin Zingler in the
microsoft.public.dotnet.languages.vb newsgroup.
Public Class Win32
Public Declare Function BitBlt Lib "gdi32" Alias "BitBlt" _
(ByVal hDestDC As Integer, ByVal x As Integer, _
ByVal y As Integer, ByVal nWidth As Integer, _
ByVal nHeight As Integer, ByVal hSrcDC As Integer, _
ByVal xSrc As Integer, ByVal ySrc As Integer, _
ByVal dwRop As Integer) As Integer
Public Declare Function GetWindowDC Lib "user32" Alias "GetWindowDC" _
(ByVal hwnd As Integer) As Integer
Public Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" _
(ByVal hwnd As Integer, ByVal hdc As Integer) As Integer
Public Const SRCCOPY As Integer = &HCC0020
End Class
Public Class Hardcopy
Public Shared Function CreateBitmap( _
ByVal Control As Control) As Bitmap
Dim gDest As Graphics
Dim hdcDest As IntPtr
Dim hdcSrc As Integer
Dim hWnd As Integer = Control.Handle.ToInt32
CreateBitmap = New Bitmap(Control.Width, Control.Height)
gDest = gDest.FromImage(CreateBitmap)
hdcSrc = Win32.GetWindowDC(hWnd)
hdcDest = gDest.GetHdc
Win32.BitBlt( _
hdcDest.ToInt32, 0, 0, Control.Width, Control.Height, _
hdcSrc, 0, 0, Win32.SRCCOPY _
)
gDest.ReleaseHdc(hdcDest)
Win32.ReleaseDC(hWnd, hdcSrc)
End Function
End Class
'In your Form:
Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Dim bmp As Bitmap
bmp = Hardcopy.CreateBitmap(Me)
bmp.Save("c:\test.bmp")
End Sub
12 How do I create a new bitmap with a new
size based on an existing bitmap?
You can simply specify the new size in the Bitmap constructr as follows:
[C#]
Bitmap bmp = new Bitmap("exisiting.bmp");
// Create a new bitmap half the size:
Bitmap bmp2 = new Bitmap(bmp, bmp.Width*0.5, bmp.Height*0.5);
this.BackgroundImage = bmp2;
[VB.Net]
Dim bmp As New Bitmap( "exisiting.bmp")
' Create a new bitmap half the size:
Dim bmp2 As New Bitmap( bmp, bmp.Width * 0.5, bmp.Height * 0.5)
Me.BackgroundImage = bmp2
If you have to specify a particular Interpolation mode while resizing use
the following code:
[C#]
Bitmap bmp = new Bitmap("exisiting.bmp");
// Create a new bitmap half the size:
Bitmap bmp2 = new Bitmap( bmp.Width*0.5, bmp.Height*0.5,
Imaging.PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bmp2);
// Set interpolation mode
g.InterpolationMode =
Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// Draw image using specified interpolation mode.
g.DrawImage(bmp, 0, 0, bmp2.Width, bmp2.Height);
this.BackgroundImage = bmp2
[VB.Net]
Dim bmp As New Bitmap( "existing.bmp")
Dim bmp2 As New Bitmap( bmp.Width * 0.5, bmp.Height * 0.5,
Imaging.PixelFormat.Format24bppRgb)
Dim g As Graphics = Graphics.FromImage(bmp2)
' Set interpolation mode
g.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
' Draw image using specified interpolation mode.
g.DrawImage(bmp, 0, 0, bmp2.Width, bmp2.Height)
Me.BackgroundImage = bmp2
13 How do I overlay one bitmap over
another?
You can create a Graphics object from the base bitmap, and then use this
Graphics object to draw the second bitmap with a transparent color that
allows the base bitmap to show through.
Bitmap Circle = (Bitmap)Image.FromFile(@"c:\circle.bmp");
Bitmap MergedBMP = (Bitmap)Image.FromFile(@"c:\cross.bmp");
Graphics g = Graphics.FromImage(Circle);
MergedBMP.MakeTransparent(Color.White);
g.DrawImage(MergedBMP,0,0);
g.Dispose();
pictureBox1.Image = Circle;
|