2 // System.Drawing.Bitmap.cs
4 // Copyright (C) 2002 Ximian, Inc. http://www.ximian.com
5 // Copyright (C) 2004 Novell, Inc. http://www.novell.com
8 // Alexandre Pigolkine (pigolkine@gmx.de)
9 // Christian Meyer (Christian.Meyer@cs.tum.edu)
10 // Miguel de Icaza (miguel@ximian.com)
11 // Jordi Mas i Hernandez (jmas@softcatala.org)
12 // Ravindra (rkumar@novell.com)
16 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
18 // Permission is hereby granted, free of charge, to any person obtaining
19 // a copy of this software and associated documentation files (the
20 // "Software"), to deal in the Software without restriction, including
21 // without limitation the rights to use, copy, modify, merge, publish,
22 // distribute, sublicense, and/or sell copies of the Software, and to
23 // permit persons to whom the Software is furnished to do so, subject to
24 // the following conditions:
26 // The above copyright notice and this permission notice shall be
27 // included in all copies or substantial portions of the Software.
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 using System.Drawing.Imaging;
40 using System.Reflection;
41 using System.Runtime.Serialization;
42 using System.Runtime.InteropServices;
43 using System.ComponentModel;
45 namespace System.Drawing
49 [Editor ("System.Drawing.Design.BitmapEditor, " + Consts.AssemblySystem_Drawing_Design, typeof (System.Drawing.Design.UITypeEditor))]
50 public sealed class Bitmap : Image
55 // required for XmlSerializer (#323246)
60 internal Bitmap (IntPtr ptr)
65 // Usually called when cloning images that need to have
66 // not only the handle saved, but also the underlying stream
67 // (when using MS GDI+ and IStream we must ensure the stream stays alive for all the life of the Image)
68 internal Bitmap(IntPtr ptr, Stream stream)
70 // under Win32 stream is owned by SD/GDI+ code
71 if (GDIPlus.RunningOnWindows ())
76 public Bitmap (int width, int height) : this (width, height, PixelFormat.Format32bppArgb)
80 public Bitmap (int width, int height, Graphics g)
83 throw new ArgumentNullException ("g");
86 Status s = GDIPlus.GdipCreateBitmapFromGraphics (width, height, g.nativeObject, out bmp);
87 GDIPlus.CheckStatus (s);
91 public Bitmap (int width, int height, PixelFormat format)
94 Status s = GDIPlus.GdipCreateBitmapFromScan0 (width, height, 0, format, IntPtr.Zero, out bmp);
95 GDIPlus.CheckStatus (s);
100 public Bitmap (Image original) : this (original, original.Width, original.Height) {}
102 public Bitmap (Stream stream) : this (stream, false) {}
104 public Bitmap (string filename) : this (filename, false) {}
106 public Bitmap (Image original, Size newSize) : this(original, newSize.Width, newSize.Height) {}
108 public Bitmap (Stream stream, bool useIcm)
110 // false: stream is owned by user code
111 nativeObject = InitFromStream (stream);
114 public Bitmap (string filename, bool useIcm)
116 if (filename == null)
117 throw new ArgumentNullException ("filename");
123 st = GDIPlus.GdipCreateBitmapFromFileICM (filename, out imagePtr);
125 st = GDIPlus.GdipCreateBitmapFromFile (filename, out imagePtr);
127 GDIPlus.CheckStatus (st);
128 nativeObject = imagePtr;
131 public Bitmap (Type type, string resource)
133 if (resource == null)
134 throw new ArgumentException ("resource");
136 // For compatibility with the .NET Framework
138 throw new NullReferenceException();
140 Stream s = type.GetTypeInfo ().Assembly.GetManifestResourceStream (type, resource);
142 string msg = Locale.GetText ("Resource '{0}' was not found.", resource);
143 throw new FileNotFoundException (msg);
146 nativeObject = InitFromStream (s);
147 // under Win32 stream is owned by SD/GDI+ code
148 if (GDIPlus.RunningOnWindows ())
152 public Bitmap (Image original, int width, int height) : this(width, height, PixelFormat.Format32bppArgb)
154 Graphics graphics = Graphics.FromImage(this);
156 graphics.DrawImage(original, 0, 0, width, height);
160 public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
164 Status status = GDIPlus.GdipCreateBitmapFromScan0 (width, height, stride, format, scan0, out bmp);
165 GDIPlus.CheckStatus (status);
169 private Bitmap (SerializationInfo info, StreamingContext context)
170 : base (info, context)
176 public Color GetPixel (int x, int y) {
180 Status s = GDIPlus.GdipBitmapGetPixel(nativeObject, x, y, out argb);
181 GDIPlus.CheckStatus (s);
183 return Color.FromArgb(argb);
186 public void SetPixel (int x, int y, Color color)
188 Status s = GDIPlus.GdipBitmapSetPixel (nativeObject, x, y, color.ToArgb ());
189 if (s == Status.InvalidParameter) {
190 // check is done in case of an error only to avoid another
191 // unmanaged call for normal (successful) calls
192 if ((this.PixelFormat & PixelFormat.Indexed) != 0) {
193 string msg = Locale.GetText ("SetPixel cannot be called on indexed bitmaps.");
194 throw new InvalidOperationException (msg);
197 GDIPlus.CheckStatus (s);
200 public Bitmap Clone (Rectangle rect, PixelFormat format)
203 Status status = GDIPlus.GdipCloneBitmapAreaI (rect.X, rect.Y, rect.Width, rect.Height,
204 format, nativeObject, out bmp);
205 GDIPlus.CheckStatus (status);
206 return new Bitmap (bmp);
209 public Bitmap Clone (RectangleF rect, PixelFormat format)
212 Status status = GDIPlus.GdipCloneBitmapArea (rect.X, rect.Y, rect.Width, rect.Height,
213 format, nativeObject, out bmp);
214 GDIPlus.CheckStatus (status);
215 return new Bitmap (bmp);
218 public static Bitmap FromHicon (IntPtr hicon)
221 Status status = GDIPlus.GdipCreateBitmapFromHICON (hicon, out bitmap);
222 GDIPlus.CheckStatus (status);
223 return new Bitmap (bitmap);
226 public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TODO: Untested
229 Status status = GDIPlus.GdipCreateBitmapFromResource (hinstance, bitmapName, out bitmap);
230 GDIPlus.CheckStatus (status);
231 return new Bitmap (bitmap);
234 [EditorBrowsable (EditorBrowsableState.Advanced)]
235 public IntPtr GetHbitmap ()
237 return GetHbitmap(Color.Gray);
240 [EditorBrowsable (EditorBrowsableState.Advanced)]
241 public IntPtr GetHbitmap (Color background)
245 Status status = GDIPlus.GdipCreateHBITMAPFromBitmap (nativeObject, out HandleBmp, background.ToArgb ());
246 GDIPlus.CheckStatus (status);
251 [EditorBrowsable (EditorBrowsableState.Advanced)]
252 public IntPtr GetHicon ()
256 Status status = GDIPlus.GdipCreateHICONFromBitmap (nativeObject, out HandleIcon);
257 GDIPlus.CheckStatus (status);
262 public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format)
264 BitmapData result = new BitmapData();
265 return LockBits (rect, flags, format, result);
269 BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
271 Status status = GDIPlus.GdipBitmapLockBits (nativeObject, ref rect, flags, format, bitmapData);
272 //NOTE: scan0 points to piece of memory allocated in the unmanaged space
273 GDIPlus.CheckStatus (status);
278 public void MakeTransparent ()
280 Color clr = GetPixel(0,0);
281 MakeTransparent (clr);
284 public void MakeTransparent (Color transparentColor)
286 // We have to draw always over a 32-bitmap surface that supports alpha channel
287 Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
288 Graphics gr = Graphics.FromImage(bmp);
289 Rectangle destRect = new Rectangle(0, 0, Width, Height);
290 ImageAttributes imageAttr = new ImageAttributes();
292 imageAttr.SetColorKey(transparentColor, transparentColor);
294 gr.DrawImage (this, destRect, 0, 0, Width, Height, GraphicsUnit.Pixel, imageAttr);
296 IntPtr oldBmp = nativeObject;
297 nativeObject = bmp.nativeObject;
298 bmp.nativeObject = oldBmp;
305 public void SetResolution (float xDpi, float yDpi)
307 Status status = GDIPlus.GdipBitmapSetResolution (nativeObject, xDpi, yDpi);
308 GDIPlus.CheckStatus (status);
311 public void UnlockBits (BitmapData bitmapdata)
313 Status status = GDIPlus.GdipBitmapUnlockBits (nativeObject, bitmapdata);
314 GDIPlus.CheckStatus (status);