главная продукты downloads форум тех. поддержка

 

Главная страница

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;
 

 

e-mail:

 

bousoft@mail.ru