public abstract class Image : MarshalByRefObject, IDisposable , ICloneable, ISerializable
{
public delegate bool GetThumbnailImageAbort();
+ private object tag;
internal IntPtr nativeObject = IntPtr.Zero;
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
MemoryStream ms = new MemoryStream ();
- this.Save (ms, ImageFormat.Bmp);
+ this.Save (ms, RawFormat);
info.AddValue ("Data", ms.ToArray ());
}
return new Bitmap (stream, useECM);
}
+ // See http://support.microsoft.com/default.aspx?scid=kb;en-us;831419 for performance discussion
+ public static Image FromStream (Stream stream, bool useECM, bool validateImageData)
+ {
+ return new Bitmap (stream, useECM);
+ }
+
public static int GetPixelFormatSize(PixelFormat pixfmt)
{
int result = 0;
status = GDIPlus.GdipGetEncoderParameterList (nativeObject, ref format, sz, rawEPList);
eps = EncoderParameters.FromNativePtr (rawEPList);
GDIPlus.CheckStatus (status);
- } catch {
+ }
+ finally {
Marshal.FreeHGlobal (rawEPList);
- throw;
}
- Marshal.FreeHGlobal (rawEPList);
-
return eps;
}
/* Get PropertyItem */
property = Marshal.AllocHGlobal (propSize);
- status = GDIPlus.GdipGetPropertyItem (nativeObject, propid, propSize,
- property);
- GDIPlus.CheckStatus (status);
- gdipProperty = (GdipPropertyItem) Marshal.PtrToStructure ((IntPtr)property,
+ try {
+ status = GDIPlus.GdipGetPropertyItem (nativeObject, propid, propSize, property);
+ GDIPlus.CheckStatus (status);
+ gdipProperty = (GdipPropertyItem) Marshal.PtrToStructure (property,
typeof (GdipPropertyItem));
- GdipPropertyItem.MarshalTo (gdipProperty, item);
-
- Marshal.FreeHGlobal (property);
+ GdipPropertyItem.MarshalTo (gdipProperty, item);
+ }
+ finally {
+ Marshal.FreeHGlobal (property);
+ }
return item;
}
- public Image GetThumbnailImage(int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callbackData)
+ public Image GetThumbnailImage (int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callbackData)
{
- Status status;
- Image ThumbNail;
- Graphics g;
+ if ((thumbWidth <= 0) || (thumbHeight <= 0))
+ throw new OutOfMemoryException ("Invalid thumbnail size");
- ThumbNail=new Bitmap(thumbWidth, thumbHeight);
- g=Graphics.FromImage(ThumbNail);
-
- status = GDIPlus.GdipDrawImageRectRectI(g.nativeObject, nativeObject,
- 0, 0, thumbWidth, thumbHeight,
- 0, 0, this.Width, this.Height,
- GraphicsUnit.Pixel, IntPtr.Zero, null, IntPtr.Zero);
- GDIPlus.CheckStatus (status);
- g.Dispose();
+ Image ThumbNail = new Bitmap (thumbWidth, thumbHeight);
+
+ using (Graphics g = Graphics.FromImage (ThumbNail)) {
+ Status status = GDIPlus.GdipDrawImageRectRectI (g.nativeObject, nativeObject,
+ 0, 0, thumbWidth, thumbHeight,
+ 0, 0, this.Width, this.Height,
+ GraphicsUnit.Pixel, IntPtr.Zero, null, IntPtr.Zero);
+
+ GDIPlus.CheckStatus (status);
+ }
- return(ThumbNail);
+ return ThumbNail;
}
Marshal.StructureToPtr (propitem, property, true);
Status status = GDIPlus.GdipSetPropertyItem (nativeObject, property);
GDIPlus.CheckStatus (status);
+ // FIXME: GdipSetPropertyItem isn't implemented in libgdiplus (but returns Ok)
+ // so who's freeing "property" ? GDI+ ?
}
// properties
/* Get PropertyItem list*/
properties = Marshal.AllocHGlobal (propsSize * propNums);
-
- status = GDIPlus.GdipGetAllPropertyItems (nativeObject, propsSize,
+ try {
+ status = GDIPlus.GdipGetAllPropertyItems (nativeObject, propsSize,
propNums, properties);
- GDIPlus.CheckStatus (status);
+ GDIPlus.CheckStatus (status);
- propSize = Marshal.SizeOf (gdipProperty);
- propPtr = properties;
+ propSize = Marshal.SizeOf (gdipProperty);
+ propPtr = properties;
- for (int i = 0; i < propNums; i++, propPtr = new IntPtr (propPtr.ToInt64 () + propSize))
- {
- gdipProperty = (GdipPropertyItem) Marshal.PtrToStructure
+ for (int i = 0; i < propNums; i++, propPtr = new IntPtr (propPtr.ToInt64 () + propSize)) {
+ gdipProperty = (GdipPropertyItem) Marshal.PtrToStructure
(propPtr, typeof (GdipPropertyItem));
- items [i] = new PropertyItem ();
- GdipPropertyItem.MarshalTo (gdipProperty, items [i]);
+ items [i] = new PropertyItem ();
+ GdipPropertyItem.MarshalTo (gdipProperty, items [i]);
+ }
+ }
+ finally {
+ Marshal.FreeHGlobal (properties);
}
-
- Marshal.FreeHGlobal (properties);
return items;
}
}
return new Size(Width, Height);
}
}
-
+
+#if NET_2_0
+ [DefaultValue (null)]
+ [LocalizableAttribute(false)]
+ [BindableAttribute(true)]
+ [TypeConverter (typeof (StringConverter))]
+ public object Tag {
+ get { return tag; }
+ set { tag = value; }
+ }
+#endif
public float VerticalResolution {
get {
float resolution;
Dispose (false);
}
- private void DisposeResources ()
- {
- Status status = GDIPlus.GdipDisposeImage (nativeObject);
- GDIPlus.CheckStatus (status);
- }
-
protected virtual void Dispose (bool disposing)
{
if (nativeObject != IntPtr.Zero){
- DisposeResources ();
+ Status status = GDIPlus.GdipDisposeImage (nativeObject);
+ // set nativeObject to null before throwing an exception
nativeObject = IntPtr.Zero;
+ GDIPlus.CheckStatus (status);
}
}
- public virtual object Clone()
- {
+ public object Clone ()
+ {
+ Bitmap b = (this as Bitmap);
+ if (b == null)
+ throw new NotImplementedException ("This Image instance isn't a Bitmap instance.");
IntPtr newimage = IntPtr.Zero;
-
- if (!(this is Bitmap))
- throw new NotImplementedException ();
-
Status status = GDIPlus.GdipCloneImage (NativeObject, out newimage);
GDIPlus.CheckStatus (status);
- if (this is Bitmap){
- return new Bitmap (newimage);
- }
-
- throw new NotImplementedException ();
+ return new Bitmap (newimage);
}
-
}
}