accord-net / framework

Machine learning, computer vision, statistics and general scientific computing for .NET
http://accord-framework.net
GNU Lesser General Public License v2.1
4.48k stars 1.99k forks source link

There are no converters to and from WPF image types #702

Open heltonbiker opened 7 years ago

heltonbiker commented 7 years ago

The System.Windows.Media.Imaging namespace contains some interesting image types, mostly deriving from ImageSource and BitmapSource base classes. Currently I have some methods, found in the internet, to convert from Bitmap to those types and back.

When I need the conversion from and to muiltidimensional arrays (for example, double[,], I found the Accord.Imaging.Converters namespace, with its ImageToMatrix and MatrixToImage classes, but they don't have method overloads converting to and from System.Windows.Media.Imaging types.

My question is: if I wanted to add those overloads, what do I need to know? Would you accept such pull request? Would this violate any API guideline?

cesarsouza commented 7 years ago

Hi @heltonbiker,

Many thanks for opening the issue and thanks a lot for the willingness to submit a pull request!

It is true that at this time, the framework doesn't offer any conversion capabilities for WPF image types. However, I have to say that I would really like to avoid adding any WPF library as a dependency in Accord.Imaging, especially because right now, it seems there are no plans in porting any WPF-specific graphics library to .NET Core.

If you would like to work on adding such functionality, I would kindly suggest adding a separate project in the Accord.NET solution, if possible called Accord.Imaging.WPF. Afterwards, feel free to add a dependency on System.Windows.Media.Imaging or any other WPF project you think would be necessary to this project. Then, I would add static classes in this project implementing extension methods for the MatrixToImage / ImageToMatrix classes adding the relevant methods to convert to and from WPF images.

If we do it in this way, we could keep the best of both worlds: keep Accord.Imaging free from dependencies on WPF libraries, and still offer a consistent API centred on the ImageToMatrix / MatrixToImage classes as long as the user is willing to add a library that depends on WPF (Accord.Imaging.WPF) to their project.

If you would be willing to create this new Accord.Imaging.WPF project, I would advise to start from a copy of the Accord.Imaging project, removing all unnecessary files, and then adding new static classes to implement such extension methods. If you would have any questions about that, please let me know, and I would be more than glad to help.

PS: When I mention project, I mean a project inside Accord.NET itself: as you might have already seen, the Accord.NET repository contains a VS solution file that is already divided into many projects, such as Accord.Imaging, Accord.MachineLearning and so on. Please note that I am not advising you to create a new GitHub repository with a totally independent project - I am just suggesting to create a new project inside the already existing Accord.NET solution file.

Thanks again for the excellent suggestion, Cesar

JimSEOW commented 7 years ago

@cesarsouza @heltonbiker Just curious, as we are moving towards .NET Standard 2.0 and XAML standard, would it be better to use these developments as guides to evolve Accord-NET. I know it is not easy to catch up with these changes, but I know @cesarsouza has already planning .NET standard 2.0 compliance.

cesarsouza commented 7 years ago

Hi @JimSEOW, do you know if NET Standard 2.0 has adopted any imaging library as a standard? If yes, I would be more than glad to implement support for it - but as far I knew (at least from some months ago) this wasn't the case.

By the way, Accord.NET already has packages targeting .NET Standard 2.0 on NuGet - support for the imaging libraries has been implemented using CoreCompat.System.Drawing since release 3.6.0.

heltonbiker commented 7 years ago

@cesarsouza thanks for the thorough explanation and incentive! I cannot be sure that I will have time to do that in the next few days, but I would like to try when I can. Specifically, I would like to receive feedback on my intended pull-request, so that it has a good quality, and I understand you are willing to do that. Thanks for now!

vpenades commented 6 years ago

@cesarsouza As far as I know, there's no official imaging library for Net Standard, but so far, the best candidate is SixLabors ImageSharp.

The library is 100% Net.Standard , and the developers are giving a lot of focus into performance. So I think it's a good candidate to be used by Accord as default image format.

It is true, thought, that most operating systems and platforms have some sort of native image format, which is convenient because it's what you typically get from media devices like webcams, etc. For that I would use ZXing's approach, to have a Net.Standard abstract "NativeImage" , and use switch & bait strategies in the nuget packages to have specific implemetations for every platform

heltonbiker commented 6 years ago

@cesarsouza I apologize for not going forward with this, but I realized I was a bit demotivated by the need to tinker with administrative structure of the project, file conventions, etc.

Do you think you could somehow use code snippets that we could exchange (copy/paste) here? I know this sounds amateurish on my part to propose that, but that could be an option just to get this particular feature done, how do you feel about it?

cesarsouza commented 6 years ago

Hi @heltonbiker,

I've finally been able to finish adding support for the WPF converters. I've also added a few more methods to convert to and from BitmapSource and Bitmaps. For instance, in the new release it should be possible to do:

// Convert WPF image to Bitmap
Bitmap bitmap = bitmapSource.ToBitmap();

// Convert Bitmap to WPF image
BitmapSource bitmapSource = bitmap.ToBitmapSource();

It will also be possible to apply the image processing filters in the framework using

BitmapSource bitmapSource = filter.Apply(bitmapSource);

As well as converting to and from matrices and arrays (the original issue raised) using

var m2bs = new MatrixToBitmapSource();
var a2bs = new ArrayToBitmapSource();
var bs2m = new BitmapSourceToMatrix();
var bs2a = new BitmapSourceToArray();

Best regards, Cesar