This project is read-only.

GDIPlusX: Enhancements/Fixes for PropertyItem class

Topics: General, Attention VFPX Admins
Sep 2, 2007 at 3:37 AM
Edited Sep 2, 2007 at 4:00 AM
There were several issues while trying to use the PropertyItem class within the GDIPlusX library. Thanks to John Gunvaldson for bringing it to our attention (GDIPlusX:Class xfcPropertyItem Properties all default to INT, Value a Problem)

Not only were there incomplete sections in the library, but even if it was working exactly as designed (modeled after the .NET PropertyItem class) it is still very cumbersome to use.

The PropertyItem.Value property in .NET is defined as a Byte[] array. The closest equivilant in VFP 9.0 is a VarBinary. This could be very cumbersome to convert your data before assigning it to the Value property. So we modified the class to allow almost any VFP data type to be assigned to the Value property, including DateTime. We convert the Value on the fly and calculate and set the Len and Type properies at the same time. While this goes outside the .NET standard we are trying to mimick, we believe this makes the library much easier to use.

Please note that the underlying data is still VarBinary, so if you try to return the Value after setting it, it will not match. Make sure you use
PropertyItem.GetValue( )
to return the value as the correct type.

We also modified the Init so you can pass the ID and Value in as the class is instantiated:
loMyProp = PropertyItem.New(999, 555888)
loMyProp = PropertyItem.New(997, DATETIME())

The next step was to finish the coding for the Image.PropertyItems property. According to .NET this property is to return an array of PropertyItem[]. Instead of returning an array, we decided to return a Collection of PropertyItem. We believe the end result is the same, but more flexible than an array.

Here is some sample code for using these newly modified classes. We would welcome any feedback related to these changes:

Note: For this to work, you must have an updated library. Grab the newest version from GDIPlusX 1.00 RC

DO (LOCFILE("System.prg"))
 
WITH _SCREEN.System.Drawing
   oBMP=.Bitmap.New(100,100)
 
   ** 4 lines of code
   oProp = .Imaging.PropertyItem.New()
   oProp.ID = 999
   oProp.Value = "Hello World"
   oBMP.SetPropertyItem(oProp)
 
   ** 2 lines of code
   oProp = .Imaging.PropertyItem.New(998,123456)
   oBMP.SetPropertyItem(oProp)
 
   ** 1 line of code
   oBMP.SetPropertyItem(.Imaging.PropertyItem.New(997,DATETIME()))
 
   ** Lets view them...
   ?oBMP.PropertyItems.Count
   ?oBMP.PropertyItems.Item(1).GetValue()
   ?oBMP.PropertyItems.Item(2).GetValue()
   ?oBMP.PropertyItems.Item(3).GetValue()
 
   ** Save our test Image as a Jpeg
   oBMP.Save("MyTestFile.jpg", .Imaging.ImageFormat.Jpeg)
   oBMP = NULL
 
   ** Open our test image and check our properties
   oImg = .Image.FromFile("MyTestFile.jpg")
   ?oImg.PropertyItems.Count
   ?oImg.PropertyItems.Item("999").GetValue()
   ?oImg.PropertyItems.Item("998").GetValue()
   ?oImg.PropertyItems.Item("997").GetValue()
 
   oProp = oImg.GetPropertyItem(999)
   ?oProp.GetValue()
ENDWITH

Thanks John. I hope this takes care of it for you.

Bo Durban
Sep 2, 2007 at 7:23 AM
Edited Sep 2, 2007 at 7:23 AM
Thank you very much Mr Durban!

This is way more than I expected, and wonderfull that you had time to look at this so rapidly, again way cool! Fwiw, I literally process over 5,000 to 50,000 TIF images during one processing cycle - update and apply new values to the custom tags written to the images (real estate PLAT maps).

The ability to use the various implementations of the class Init() are totally cool.

I'll get right back into this in the morning and run through the full production process "ASCII" and "LONG" data types (Types = 2 + 4)...

GDIPlusX Rocks!

John C. Gunvaldson
www.fox-net.com
San Diego, CA




binarybo wrote:
There were several issues while trying to use the PropertyItem class within the GDIPlusX library. Thanks to John Gunvaldson for bringing it to our attention (GDIPlusX:Class xfcPropertyItem Properties all default to INT, Value a Problem)

Not only were there incomplete sections in the library, but even if it was working exactly as designed (modeled after the .NET PropertyItem class) it is still very cumbersome to use.

The PropertyItem.Value property in .NET is defined as a Byte[] array. The closest equivilant in VFP 9.0 is a VarBinary. This could be very cumbersome to convert your data before assigning it to the Value property. So we modified the class to allow almost any VFP data type to be assigned to the Value property, including DateTime. We convert the Value on the fly and calculate and set the Len and Type properies at the same time. While this goes outside the .NET standard we are trying to mimick, we believe this makes the library much easier to use.

Please note that the underlying data is still VarBinary, so if you try to return the Value after setting it, it will not match. Make sure you use
PropertyItem.GetValue( )
to return the value as the correct type.

We also modified the Init so you can pass the ID and Value in as the class is instantiated:
loMyProp = PropertyItem.New(999, 555888)
loMyProp = PropertyItem.New(997, DATETIME())

The next step was to finish the coding for the Image.PropertyItems property. According to .NET this property is to return an array of PropertyItem[]. Instead of returning an array, we decided to return a Collection of PropertyItem. We believe the end result is the same, but more flexible than an array.

Here is some sample code for using these newly modified classes. We would welcome any feedback related to these changes:

Note: For this to work, you must have an updated library. Grab the newest version from GDIPlusX 1.00 RC

DO (LOCFILE("System.prg"))
 
WITH _SCREEN.System.Drawing
   oBMP=.Bitmap.New(100,100)
 
   ** 4 lines of code
   oProp = .Imaging.PropertyItem.New()
   oProp.ID = 999
   oProp.Value = "Hello World"
   oBMP.SetPropertyItem(oProp)
 
   ** 2 lines of code
   oProp = .Imaging.PropertyItem.New(998,123456)
   oBMP.SetPropertyItem(oProp)
 
   ** 1 line of code
   oBMP.SetPropertyItem(.Imaging.PropertyItem.New(997,DATETIME()))
 
   ** Lets view them...
   ?oBMP.PropertyItems.Count
   ?oBMP.PropertyItems.Item(1).GetValue()
   ?oBMP.PropertyItems.Item(2).GetValue()
   ?oBMP.PropertyItems.Item(3).GetValue()
 
   ** Save our test Image as a Jpeg
   oBMP.Save("MyTestFile.jpg", .Imaging.ImageFormat.Jpeg)
   oBMP = NULL
 
   ** Open our test image and check our properties
   oImg = .Image.FromFile("MyTestFile.jpg")
   ?oImg.PropertyItems.Count
   ?oImg.PropertyItems.Item("999").GetValue()
   ?oImg.PropertyItems.Item("998").GetValue()
   ?oImg.PropertyItems.Item("997").GetValue()
 
   oProp = oImg.GetPropertyItem(999)
   ?oProp.GetValue()
ENDWITH

Thanks John. I hope this takes care of it for you.

Bo Durban