GithubHelp home page GithubHelp logo

stakx / wic Goto Github PK

View Code? Open in Web Editor NEW
14.0 4.0 7.0 122 KB

A COM interop library for .NET that makes Windows Imaging Component (WIC) available to managed code.

License: MIT License

C# 100.00%
component-object-model com-interop windows imaging image-processing wic windows-imaging-component csharp c-sharp dotnet

wic's Introduction

WIC

A COM interop library for .NET that makes Windows Imaging Component (WIC) available to managed code.

NuGet

What is the Windows Imaging Component (WIC)?

"The Windows Imaging Component (WIC) is a Component Object Model based imaging codec framework introduced in Windows Vista (…) for working with and processing digital images and image metadata." — from the Wikipedia article

Windows Imaging Component allows you to accomplish tasks such as:

  • decoding and encoding bitmap images or single bitmap image frames in various formats (GIF, ICO, JPEG, PNG, TIFF, and more)
  • reading and writing image metadata
  • converting bitmaps to different pixel formats (bit depth, channels)
  • transforming bitmaps (clip, flip horizontally or vertically, rotate by 90° angles, scale)

Why would you want to use stakx.WIC?

I originally started this project because I needed a library to do some fairly simple image processing… inside an ASP.NET web application. And it is this last bit that introduces a few problems. The .NET Framework does not come with any image processing functionality that is officially supported in server-side code:

  1. There is the System.Drawing namespace. The facilities in this namespace are based on the GDI+ API. It is officially unsupported in server-side code. (Although it usually works just fine, if you know how to avoid memory leaks and work around performance issues; regarding this topic, I'd recommend Nathanael Jones' article "20 Image Resizing Pitfalls".)

  2. There is the System.Windows.Media.Imaging namespace. This one belongs to the Windows Presentation Foundation (WPF) UI framework and contains thin wrappers around the WIC. Being part of a UI framework, it is also not an ideal candidate for server-side scenarios. (But like GDI+, it often works just fine.)

The nice thing about the WIC is that it is officially supported on Windows servers! So if you can find a way to use it directly, then you're all good. And this is exactly what this project offers: a set of type definitions so that you can use the WIC from .NET.

How do you get started?

  1. Familiarize yourself with the WIC, if you don't know it yet. See e.g. the Windows Imaging Component documentation on MSDN.

  2. Add the NuGet package stakx.WIC to your project. Alternatively, you can compile this project yourself (you will need Visual Studio 2017 for this), and then add a reference to the built WIC.dll assembly to your project.

  3. In your code, start by instantiating a WICImagingFactory object. Most other WIC components can be created directly or indirectly through this factory object.

Is there any example code?

This project page does currently not provide any samples to show how exactly one would get stuff done using the WIC API. Until I find the time to write some sample code in the future, please refer to the the WIC samples on MSDN. I have strived to keep the COM interop types in this project as close as possible to the original COM type definitions. This should make it fairly easy for you to draw the connection between what you read on MSDN, and this .NET library.

wic's People

Contributors

jpmikkers avatar stakx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

wic's Issues

Drop the user name prefix, if possible

Inspired by Jeff Atwood's "A Modest Namespace Proposal" and this discussion on AutoFixture (not that my project will ever be as popular as AutoFixture, of course), I think my user name should go. If anyone forks the project or uses it, there's probably no good reason why they should have to see my user name all the time, and it seems unlikely that they would work with another library using a namespace named WIC.

This would affect the following:

  • GitHub repository name
  • C# namespace
  • directory and project file names
  • NuGet package name

Representing a pointer to pixel data as `byte[]` is disadvantageous

Some methods have a "pointer to pixel data" parameter; for example:

  • IWICBitmapFrameEncode.WritePixels
  • IWICBitmapSource.CopyPixels
  • IWICImagingFactory.CreateBitmapFromMemory

These parameters are currently typed as byte[], which is not an ideal choice, for at least two reasons:

  1. Bitmaps can easily occupy a lot of memory. If a bitmap's complete pixel data is represented as a byte[] array, this will cause LOH (Large Object Heap) allocations. These should be avoided if possible.

    One solution would be to represent pointers to pixel data as IntPtr instead, and allocate buffers using Marshal.AllocCoTaskMem. Unmanaged memory blocks are invisible to the garbage collector, therefore there would be no LOH allocation; however some helper methods might be necessary to prevent unmanaged memory leaks.

  2. Some WIC methods that deal with pixel data allow passing a pointer and a "stride" value (which allows jumping to the next row in the pixel buffer). Since byte[] arrays cannot be "offset", there is no way to specify any other starting point than the very first pixel in the array (usually the top left).

    Again, the likely solution is to represent the pixel data buffer as IntPtr, and then possibly providing overloads for byte*, and/or byte[], and/or ArraySegment<byte>. Need to check what makes the most sense in practical scenarios.

Interfaces `ISequentialStream`, `IStream`, and `IWICStream` appear to be declared incorrectly

Using the stream types ISequentialStream, IStream, and IWICStream yields some unexpected results. For example, calling IStream.Commit(STGC_DEFAULT) sometimes returns a "not implemented" error, which seems rather unlikely; especially since there are code examples on MSDN calling this method on a WIC stream (e.g. here). So probably our interfaces aren't declared correctly.

One possible error source are the duplicate [local] and [remote] methods in the stream interfaces. Not clear whether they both need to be present in the .NET interfaces, or just one each.

One possible solution would be to compare our declaration with that of the pre-defined type System.Runtime.InteropServices.ComTypes.IStream, and see whether there are any differences… or just switch over to that type.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.