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.Runtime.Serialization;
41 using System.Runtime.InteropServices;
42 using System.ComponentModel;
43 using System.Security.Permissions;
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
56 // required for XmlSerializer (#323246)
62 internal Bitmap (IntPtr ptr)
67 // Usually called when cloning images that need to have
68 // not only the handle saved, but also the underlying stream
69 // (when using MS GDI+ and IStream we must ensure the stream stays alive for all the life of the Image)
70 internal Bitmap(IntPtr ptr, Stream stream)
72 // under Win32 stream is owned by SD/GDI+ code
73 if (GDIPlus.RunningOnWindows ())
78 public Bitmap (int width, int height) : this (width, height, PixelFormat.Format32bppArgb)
82 public Bitmap (int width, int height, Graphics g)
85 throw new ArgumentNullException ("g");
88 Status s = GDIPlus.GdipCreateBitmapFromGraphics (width, height, g.nativeObject, out bmp);
89 GDIPlus.CheckStatus (s);
93 public Bitmap (int width, int height, PixelFormat format)
96 Status s = GDIPlus.GdipCreateBitmapFromScan0 (width, height, 0, format, IntPtr.Zero, out bmp);
97 GDIPlus.CheckStatus (s);
102 public Bitmap (Image original) : this (original, original.Width, original.Height) {}
104 public Bitmap (Stream stream) : this (stream, false) {}
106 public Bitmap (string filename) : this (filename, false) {}
108 public Bitmap (Image original, Size newSize) : this(original, newSize.Width, newSize.Height) {}
110 public Bitmap (Stream stream, bool useIcm)
112 // false: stream is owned by user code
113 nativeObject = InitFromStream (stream);
116 public Bitmap (string filename, bool useIcm)
118 if (filename == null)
119 throw new ArgumentNullException ("filename");
125 st = GDIPlus.GdipCreateBitmapFromFileICM (filename, out imagePtr);
127 st = GDIPlus.GdipCreateBitmapFromFile (filename, out imagePtr);
129 GDIPlus.CheckStatus (st);
130 nativeObject = imagePtr;
133 public Bitmap (Type type, string resource)
135 if (resource == null)
136 throw new ArgumentException ("resource");
138 Stream s = type.Assembly.GetManifestResourceStream (type, resource);
140 string msg = Locale.GetText ("Resource '{0}' was not found.", resource);
141 throw new FileNotFoundException (msg);
144 nativeObject = InitFromStream (s);
145 // under Win32 stream is owned by SD/GDI+ code
146 if (GDIPlus.RunningOnWindows ())
150 public Bitmap (Image original, int width, int height) : this(width, height, PixelFormat.Format32bppArgb)
152 Graphics graphics = Graphics.FromImage(this);
154 graphics.DrawImage(original, 0, 0, width, height);
158 public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
162 Status status = GDIPlus.GdipCreateBitmapFromScan0 (width, height, stride, format, scan0, out bmp);
163 GDIPlus.CheckStatus (status);
167 private Bitmap (SerializationInfo info, StreamingContext context)
168 : base (info, context)
174 public Color GetPixel (int x, int y) {
178 Status s = GDIPlus.GdipBitmapGetPixel(nativeObject, x, y, out argb);
179 GDIPlus.CheckStatus (s);
181 return Color.FromArgb(argb);
184 public void SetPixel (int x, int y, Color color)
186 Status s = GDIPlus.GdipBitmapSetPixel (nativeObject, x, y, color.ToArgb ());
187 if (s == Status.InvalidParameter) {
188 // check is done in case of an error only to avoid another
189 // unmanaged call for normal (successful) calls
190 if ((this.PixelFormat & PixelFormat.Indexed) != 0) {
191 string msg = Locale.GetText ("SetPixel cannot be called on indexed bitmaps.");
193 throw new InvalidOperationException (msg);
195 throw new Exception (msg);
199 GDIPlus.CheckStatus (s);
202 public Bitmap Clone (Rectangle rect, PixelFormat format)
205 Status status = GDIPlus.GdipCloneBitmapAreaI (rect.X, rect.Y, rect.Width, rect.Height,
206 format, nativeObject, out bmp);
207 GDIPlus.CheckStatus (status);
208 return new Bitmap (bmp);
211 public Bitmap Clone (RectangleF rect, PixelFormat format)
214 Status status = GDIPlus.GdipCloneBitmapArea (rect.X, rect.Y, rect.Width, rect.Height,
215 format, nativeObject, out bmp);
216 GDIPlus.CheckStatus (status);
217 return new Bitmap (bmp);
220 public static Bitmap FromHicon (IntPtr hicon)
223 Status status = GDIPlus.GdipCreateBitmapFromHICON (hicon, out bitmap);
224 GDIPlus.CheckStatus (status);
225 return new Bitmap (bitmap);
228 public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TODO: Untested
231 Status status = GDIPlus.GdipCreateBitmapFromResource (hinstance, bitmapName, out bitmap);
232 GDIPlus.CheckStatus (status);
233 return new Bitmap (bitmap);
236 [EditorBrowsable (EditorBrowsableState.Advanced)]
237 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
238 public IntPtr GetHbitmap ()
240 return GetHbitmap(Color.Gray);
243 [EditorBrowsable (EditorBrowsableState.Advanced)]
244 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
245 public IntPtr GetHbitmap (Color background)
249 Status status = GDIPlus.GdipCreateHBITMAPFromBitmap (nativeObject, out HandleBmp, background.ToArgb ());
250 GDIPlus.CheckStatus (status);
255 [EditorBrowsable (EditorBrowsableState.Advanced)]
256 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
257 public IntPtr GetHicon ()
261 Status status = GDIPlus.GdipCreateHICONFromBitmap (nativeObject, out HandleIcon);
262 GDIPlus.CheckStatus (status);
267 public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format)
269 BitmapData result = new BitmapData();
270 return LockBits (rect, flags, format, result);
276 BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
278 Status status = GDIPlus.GdipBitmapLockBits (nativeObject, ref rect, flags, format, bitmapData);
279 //NOTE: scan0 points to piece of memory allocated in the unmanaged space
280 GDIPlus.CheckStatus (status);
285 public void MakeTransparent ()
287 Color clr = GetPixel(0,0);
288 MakeTransparent (clr);
291 public void MakeTransparent (Color transparentColor)
293 // We have to draw always over a 32-bitmap surface that supports alpha channel
294 Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
295 Graphics gr = Graphics.FromImage(bmp);
296 Rectangle destRect = new Rectangle(0, 0, Width, Height);
297 ImageAttributes imageAttr = new ImageAttributes();
299 imageAttr.SetColorKey(transparentColor, transparentColor);
301 gr.DrawImage (this, destRect, 0, 0, Width, Height, GraphicsUnit.Pixel, imageAttr);
303 IntPtr oldBmp = nativeObject;
304 nativeObject = bmp.nativeObject;
305 bmp.nativeObject = oldBmp;
312 public void SetResolution (float xDpi, float yDpi)
314 Status status = GDIPlus.GdipBitmapSetResolution (nativeObject, xDpi, yDpi);
315 GDIPlus.CheckStatus (status);
318 public void UnlockBits (BitmapData bitmapdata)
320 Status status = GDIPlus.GdipBitmapUnlockBits (nativeObject, bitmapdata);
321 GDIPlus.CheckStatus (status);