1 // 2 // System.Drawing.Bitmap.cs 3 // 4 // Copyright (C) 2002 Ximian, Inc. http://www.ximian.com 5 // Copyright (C) 2004 Novell, Inc. http://www.novell.com 6 // 7 // Authors: 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) 13 // 14 15 // 16 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) 17 // 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: 25 // 26 // The above copyright notice and this permission notice shall be 27 // included in all copies or substantial portions of the Software. 28 // 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. 36 // 37 38 using System.IO; 39 using System.Drawing.Imaging; 40 using System.Reflection; 41 using System.Runtime.Serialization; 42 using System.Runtime.InteropServices; 43 using System.ComponentModel; 44 45 namespace System.Drawing 46 { 47 [Serializable] 48 [ComVisible (true)] 49 [Editor ("System.Drawing.Design.BitmapEditor, " + Consts.AssemblySystem_Drawing_Design, typeof (System.Drawing.Design.UITypeEditor))] 50 public sealed class Bitmap : Image 51 { 52 #region constructors 53 // constructors 54 55 // required for XmlSerializer (#323246) Bitmap()56 private Bitmap () 57 { 58 } 59 Bitmap(IntPtr ptr)60 internal Bitmap (IntPtr ptr) 61 { 62 nativeObject = ptr; 63 } 64 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) Bitmap(IntPtr ptr, Stream stream)68 internal Bitmap(IntPtr ptr, Stream stream) 69 { 70 // under Win32 stream is owned by SD/GDI+ code 71 if (GDIPlus.RunningOnWindows ()) 72 this.stream = stream; 73 nativeObject = ptr; 74 } 75 Bitmap(int width, int height)76 public Bitmap (int width, int height) : this (width, height, PixelFormat.Format32bppArgb) 77 { 78 } 79 Bitmap(int width, int height, Graphics g)80 public Bitmap (int width, int height, Graphics g) 81 { 82 if (g == null) 83 throw new ArgumentNullException ("g"); 84 85 IntPtr bmp; 86 Status s = GDIPlus.GdipCreateBitmapFromGraphics (width, height, g.nativeObject, out bmp); 87 GDIPlus.CheckStatus (s); 88 nativeObject = bmp; 89 } 90 Bitmap(int width, int height, PixelFormat format)91 public Bitmap (int width, int height, PixelFormat format) 92 { 93 IntPtr bmp; 94 Status s = GDIPlus.GdipCreateBitmapFromScan0 (width, height, 0, format, IntPtr.Zero, out bmp); 95 GDIPlus.CheckStatus (s); 96 nativeObject = bmp; 97 98 } 99 Bitmap(Image original)100 public Bitmap (Image original) : this (original, original.Width, original.Height) {} 101 Bitmap(Stream stream)102 public Bitmap (Stream stream) : this (stream, false) {} 103 Bitmap(string filename)104 public Bitmap (string filename) : this (filename, false) {} 105 Bitmap(Image original, Size newSize)106 public Bitmap (Image original, Size newSize) : this(original, newSize.Width, newSize.Height) {} 107 Bitmap(Stream stream, bool useIcm)108 public Bitmap (Stream stream, bool useIcm) 109 { 110 // false: stream is owned by user code 111 nativeObject = InitFromStream (stream); 112 } 113 Bitmap(string filename, bool useIcm)114 public Bitmap (string filename, bool useIcm) 115 { 116 if (filename == null) 117 throw new ArgumentNullException ("filename"); 118 119 IntPtr imagePtr; 120 Status st; 121 122 if (useIcm) 123 st = GDIPlus.GdipCreateBitmapFromFileICM (filename, out imagePtr); 124 else 125 st = GDIPlus.GdipCreateBitmapFromFile (filename, out imagePtr); 126 127 GDIPlus.CheckStatus (st); 128 nativeObject = imagePtr; 129 } 130 Bitmap(Type type, string resource)131 public Bitmap (Type type, string resource) 132 { 133 if (resource == null) 134 throw new ArgumentException ("resource"); 135 136 // For compatibility with the .NET Framework 137 if (type == null) 138 throw new NullReferenceException(); 139 140 Stream s = type.GetTypeInfo ().Assembly.GetManifestResourceStream (type, resource); 141 if (s == null) { 142 string msg = Locale.GetText ("Resource '{0}' was not found.", resource); 143 throw new FileNotFoundException (msg); 144 } 145 146 nativeObject = InitFromStream (s); 147 // under Win32 stream is owned by SD/GDI+ code 148 if (GDIPlus.RunningOnWindows ()) 149 stream = s; 150 } 151 Bitmap(Image original, int width, int height)152 public Bitmap (Image original, int width, int height) : this(width, height, PixelFormat.Format32bppArgb) 153 { 154 Graphics graphics = Graphics.FromImage(this); 155 156 graphics.DrawImage(original, 0, 0, width, height); 157 graphics.Dispose(); 158 } 159 Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0)160 public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0) 161 { 162 IntPtr bmp; 163 164 Status status = GDIPlus.GdipCreateBitmapFromScan0 (width, height, stride, format, scan0, out bmp); 165 GDIPlus.CheckStatus (status); 166 nativeObject = bmp; 167 } 168 Bitmap(SerializationInfo info, StreamingContext context)169 private Bitmap (SerializationInfo info, StreamingContext context) 170 : base (info, context) 171 { 172 } 173 174 #endregion 175 // methods GetPixel(int x, int y)176 public Color GetPixel (int x, int y) { 177 178 int argb; 179 180 Status s = GDIPlus.GdipBitmapGetPixel(nativeObject, x, y, out argb); 181 GDIPlus.CheckStatus (s); 182 183 return Color.FromArgb(argb); 184 } 185 SetPixel(int x, int y, Color color)186 public void SetPixel (int x, int y, Color color) 187 { 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); 195 } 196 } 197 GDIPlus.CheckStatus (s); 198 } 199 Clone(Rectangle rect, PixelFormat format)200 public Bitmap Clone (Rectangle rect, PixelFormat format) 201 { 202 IntPtr bmp; 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); 207 } 208 Clone(RectangleF rect, PixelFormat format)209 public Bitmap Clone (RectangleF rect, PixelFormat format) 210 { 211 IntPtr bmp; 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); 216 } 217 FromHicon(IntPtr hicon)218 public static Bitmap FromHicon (IntPtr hicon) 219 { 220 IntPtr bitmap; 221 Status status = GDIPlus.GdipCreateBitmapFromHICON (hicon, out bitmap); 222 GDIPlus.CheckStatus (status); 223 return new Bitmap (bitmap); 224 } 225 FromResource(IntPtr hinstance, string bitmapName)226 public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TODO: Untested 227 { 228 IntPtr bitmap; 229 Status status = GDIPlus.GdipCreateBitmapFromResource (hinstance, bitmapName, out bitmap); 230 GDIPlus.CheckStatus (status); 231 return new Bitmap (bitmap); 232 } 233 234 [EditorBrowsable (EditorBrowsableState.Advanced)] GetHbitmap()235 public IntPtr GetHbitmap () 236 { 237 return GetHbitmap(Color.Gray); 238 } 239 240 [EditorBrowsable (EditorBrowsableState.Advanced)] GetHbitmap(Color background)241 public IntPtr GetHbitmap (Color background) 242 { 243 IntPtr HandleBmp; 244 245 Status status = GDIPlus.GdipCreateHBITMAPFromBitmap (nativeObject, out HandleBmp, background.ToArgb ()); 246 GDIPlus.CheckStatus (status); 247 248 return HandleBmp; 249 } 250 251 [EditorBrowsable (EditorBrowsableState.Advanced)] GetHicon()252 public IntPtr GetHicon () 253 { 254 IntPtr HandleIcon; 255 256 Status status = GDIPlus.GdipCreateHICONFromBitmap (nativeObject, out HandleIcon); 257 GDIPlus.CheckStatus (status); 258 259 return HandleIcon; 260 } 261 LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format)262 public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format) 263 { 264 BitmapData result = new BitmapData(); 265 return LockBits (rect, flags, format, result); 266 } 267 268 public LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)269 BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData) 270 { 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); 274 275 return bitmapData; 276 } 277 MakeTransparent()278 public void MakeTransparent () 279 { 280 Color clr = GetPixel(0,0); 281 MakeTransparent (clr); 282 } 283 MakeTransparent(Color transparentColor)284 public void MakeTransparent (Color transparentColor) 285 { 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(); 291 292 imageAttr.SetColorKey(transparentColor, transparentColor); 293 294 gr.DrawImage (this, destRect, 0, 0, Width, Height, GraphicsUnit.Pixel, imageAttr); 295 296 IntPtr oldBmp = nativeObject; 297 nativeObject = bmp.nativeObject; 298 bmp.nativeObject = oldBmp; 299 300 gr.Dispose(); 301 bmp.Dispose(); 302 imageAttr.Dispose(); 303 } 304 SetResolution(float xDpi, float yDpi)305 public void SetResolution (float xDpi, float yDpi) 306 { 307 Status status = GDIPlus.GdipBitmapSetResolution (nativeObject, xDpi, yDpi); 308 GDIPlus.CheckStatus (status); 309 } 310 UnlockBits(BitmapData bitmapdata)311 public void UnlockBits (BitmapData bitmapdata) 312 { 313 Status status = GDIPlus.GdipBitmapUnlockBits (nativeObject, bitmapdata); 314 GDIPlus.CheckStatus (status); 315 } 316 } 317 } 318