Using WriteableBitmapEx in commercial software

Developer
Dec 4, 2011 at 8:57 PM

Hello there, 

I'm interesting in using the excellent WriteableBitmapEx library in a commercial software product. I've read the MS-Public license and believe its ok to use it so long as I include the copyright. Can you confirm?

I've had to make some modifications to the code as my product is dual deployed WPF/Silverlight (also Win7 phone in the future), hence I am using the unofficial WPF version. This has some bugs, I'd be happy to update it and commit back if you are interested. 

For the record, I say commercial, I haven't sold anything yet and its a long shot that I will, but just want to make sure this is ok. If the product does do well I'd be more than happy to advertise this excellent library. 

Best regards, 
Andrew 

Coordinator
Dec 4, 2011 at 9:19 PM

It's fine as long as you give credits to the library somewhere.

I'd be interested to see your final product.

Contributions are always welcome. Please create a bug report and attach the zipped WPF versions.

 

- Rene Schulte

Developer
Dec 4, 2011 at 10:28 PM

Great, appreciate it :) 

Regarding the WPF version, I don't think it compiles out the box. I had to add some #IF Silverlight statements to lock the bitmap here and there. It's fairly out of date but very useful as WPF lacks a decent API to draw to writeable bitmap. 

I've been using a modified version of the WPF version but I think I may upgrade to the latest SL and code in the #If statements for WPF where applicable. 

I'd be happy to share it once done. 

 

Andrew

Dec 6, 2011 at 10:49 PM
Edited Dec 6, 2011 at 10:51 PM

I would be interested in seeing the wpf version updated as well. This library has been very helpful on some of my projects.

Developer
Dec 12, 2011 at 10:44 AM
Edited Dec 12, 2011 at 11:22 AM

Hello there,

So I spent some time this weekend updating the WPF version. I have not completed it, am doing testing.

What I have done is I checked out the latest source from codeplex and in-place (in the Silverlight files) I have made them dual-configured for WPF and Silverlight. I realised that you used to have the WPF version in its own branch. I believe the reason for this was because the code was hard to read and maintain with all the Preprocessor statements mixed in the methods, hence you did not want to pollute the trunk with preprocessor directives.

I have made the SL code compatible with WPF in trunk as I want to keep up to date with new features in the SL version and not do all this work again when new features are released. I believe I have come up with a viable solution to keep the code readable and maintainable throughout (reduction of preprocessor statements in code). I hope that is ok.

In order to reduce the number of hacks (#if SILVERLIGHT etc...) I created a helper class and moved all hacking to there. You will see when you get the source code. I created a class called BitmapContext which implements IDisposable and exposes the Pixels property for the bitmap, either of type int[] for Silverlight or int * for WPF (conditional compilation). the result is quite unified code throughout the extensions with minimal preprocessor hacks. You can call this and it works in both WPF and SL. BitmapContext also contains SL and WPF specific implementations of Copy (using memcpy for WPF and Buffer.BlockCopy for SL) and Clear.

The WBEx extension methods use BitmapContext instead of calling directly writeableBitmap.Pixels, Lock and Unlock as follows:

// calls an extension method to return a type BitmapContext
// which implements IDisposable. 
// 
// Internally BitmapContext
// has many #if SILVERLIGHT hacks to keep the rest of 
// the code as clean as possible. 
// 
// When the BitmapContext is constructed if WPF it Locks 
// the bitmap
// 
// When the BitmapContext
// is disposed if WPF it unlocks the bitmap and invalidates
using (var context = bmp.GetBitmapContext())
{
   // Example usage. The Pixels property exposes int[] for SL and int* for WPF
   var pixels = context.Pixels;
   pixels[i] = newValue; 
}

Also, new bitmaps can be created using a BitmapFactory class

// Replacement for new WriteableBitmap(x, y) as SL and WPF
// have different constructors for this class
var newBitmap = BitmapFactory.New(pixelWidth, pixelHeight);

The result is unified code with minimal preprocessor hacks in the extension methods themselves. The preprocessor directives have been moved to the BitmapContext and BitmapFactory classes, resulting in cleaner code but cross-platform compatibility.

I am in the process of testing this. So far it compiles across WPF/SL and all Silverlight examples run fine with no discernable drop in performance. I am creating WPF examples to mirror the SL and when I get these working I will send the files. I have not tested against Windows Phone.

Are you interested in this implementation? I can zip up and put on my website if you want, or email to you direct. For your records, the project I am working on with WBEx is described on my website.

This is why I am interested in keeping WBEx up to date as it is an excellent and powerful library! I also have some extensions I wish to add such as a BlitQuad method which I am working on to allow gradient filled polygons to be drawn using a combination of Blit and DrawQuad. I am also interested in chaining operations so you only get one bmp.Lock / bmp.Unlock operation for multiple calls. I can do this via the BitmapContext ctor/dispose method.

Best regards,

Coordinator
Dec 12, 2011 at 10:49 PM

Sounds very good to me and very useful for the WinRT port I plan for the near future. Thanks for giving back. :)

When you're done, just send the zip to me and I will look through and also test on WP7. BTW, why don't you also release a WP7 version of your graph lib? ;)

 

- René 

Developer
Dec 12, 2011 at 11:21 PM

Ah you discovered my cunning plan ^_^ 

I am planning to release a WP7 version but for the moment I'm concentrating on getting just the WPF / SL versions ready! It's a lot of work as you can imagine. WinRT also interests me so do let us know when you do this. I sent you the zip by email. I reviewed the code and there are 23 preprocessor hacks in total. 6 are in BitmapContext (covering all Lock/Unlock, .Pixels for the bitmap). There is one at the header of each file (including unsafe in the class definition for WPF). There are a handful dotted around the code. For instance:

#if SILVERLIGHT
        public static int[] Resize(int[] pixels, int widthSource, int heightSource, int width, int height, Interpolation interpolation)
#else
        public static int[] Resize(int* pixels, int widthSource, int heightSource, int width, int height, Interpolation interpolation)
#endif
 I may be able to solve these by passing a BitmapContext to the function instead of the pixels array or pointer (you'll see when you get the code). This would reduce the preprocessor count further. 

Developer
Dec 13, 2011 at 9:31 AM

Ok I did this (above) so the unified code now looks like this

public static int[] Resize(BitmapContext context, int widthSource, int heightSource, int width, int height, Interpolation interpolation)
{
     var pixels = context.Pixels; 
     // ... 
}

As a result almost all preprocessor hacks are kept to the BitmapContext struct. There are very few in the actual code making it easier to maintain and neater to read. I tried to email the code yesterday but had a failure delivery. I will do so today so you can evaluate and test it. Please test thoroughly!

Coordinator
Dec 13, 2011 at 10:27 AM

Nice. Just sent you another DM with my email address.

BTW, there's no need to hurry up. Take your time until you're satisfied with the result. :)

 

- rene

Developer
Dec 13, 2011 at 9:16 PM

Done, i've emailed it to you. I had a lot of problems as Gmail was incorrectly reporting that the zip file had an .exe. So I sent as a rar file instead. 

Let me know if it works :)

Andrew