{"id":15060009,"url":"https://github.com/smourier/wicnet","last_synced_at":"2025-04-10T05:43:26.508Z","repository":{"id":45525131,"uuid":"329574863","full_name":"smourier/WicNet","owner":"smourier","description":".NET interop classes for WIC (Windows Imaging Component), Direct2D and DirectWrite. With .NET 8+ AOT support","archived":false,"fork":false,"pushed_at":"2024-10-28T17:25:21.000Z","size":115954,"stargazers_count":27,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-29T11:34:49.288Z","etag":null,"topics":["direct2d","dotnet","dotnet-aot","dotnet-core","dwrite","imaging","wic","winui3"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smourier.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-14T10:01:29.000Z","updated_at":"2024-10-28T17:25:38.000Z","dependencies_parsed_at":"2023-02-01T02:15:39.861Z","dependency_job_id":"5e53868d-491b-4ae8-971a-a63bf8e28400","html_url":"https://github.com/smourier/WicNet","commit_stats":{"total_commits":55,"total_committers":2,"mean_commits":27.5,"dds":0.09090909090909094,"last_synced_commit":"7f0c55dad6dedab8f7f9d17fa8956b796446944b"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FWicNet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FWicNet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FWicNet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smourier%2FWicNet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smourier","download_url":"https://codeload.github.com/smourier/WicNet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248166780,"owners_count":21058479,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["direct2d","dotnet","dotnet-aot","dotnet-core","dwrite","imaging","wic","winui3"],"created_at":"2024-09-24T22:51:08.151Z","updated_at":"2025-04-10T05:43:26.477Z","avatar_url":"https://github.com/smourier.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WicNet\r\n.NET interop classes for WIC (Windows Imaging Component) Direct2D, and DirectWrite, based on netstandard 2.0, with zero dependency (except for DirectN https://www.nuget.org/packages/DirectNStandard/)\r\n\r\nNuget Package is available here: https://www.nuget.org/packages/WicNet\r\n\r\nMain projects are:\r\n* **WicNet** is the main library that you can use to program WIC in .NET. It's .NET standard based so compatible with .NET Framework and .NET Core 6+ projects.\r\n* **WicNetCore** is a .NET 8+ and AOT-friendly version of **WicNet**. It's still a work in progress.\r\n* **WicNetExplorer** is a Winforms-based GUI sample program that demonstrates how to use **WicNet**, see below for more information.\r\n* **WicNet.WinUI3Tests** is a simple project that demonstrates WIC and WinRT/WinUI3's imaging classes (notably `SoftwareBitmap`).\r\n\r\nSimple use case is load \u0026 save:\r\n\r\n    using (var bmp = WicBitmapSource.Load(@\"myJpegFile.jpg\"))\r\n    {\r\n        bmp.Save(\"myHeicFile.heic\");\r\n    }\r\n\r\nDraw ellipse over an image and save (uses D2D):\r\n\r\n    using (var bmp = WicBitmapSource.Load(\"MyImag.jpg\"))\r\n    {\r\n        bmp.ConvertTo(WicPixelFormat.GUID_WICPixelFormat32bppBGR);  // needed to be able to work with Direct2D\r\n        var width = 200;\r\n        var height = width * bmp.Height / bmp.Width;\r\n        using (var memBmp = new WicBitmapSource(width, height, WicPixelFormat.GUID_WICPixelFormat32bppPRGBA))\r\n        using (var rt = memBmp.CreateDeviceContext())\r\n        using (var dbmp = rt.CreateBitmapFromWicBitmap(bmp.ComObject))\r\n        using (var brush = rt.CreateSolidColorBrush(_D3DCOLORVALUE.Red))\r\n        {\r\n            rt.BeginDraw();\r\n            rt.DrawBitmap(dbmp, destinationRectangle: new D2D_RECT_F(new D2D_SIZE_F(memBmp.Size)));\r\n            rt.DrawEllipse(new D2D1_ELLIPSE(width / 2, height / 2, Math.Min(width, height) / 2), brush, 4);\r\n            rt.EndDraw();\r\n            memBmp.Save(\"ellipse.jpg\");\r\n        }\r\n    }\r\n\r\nRotate image, convert to grayscale and save (uses Direct2D effects):\r\n\r\n    static void RotateAndGrayscale()\r\n    {\r\n        using (var bmp = WicBitmapSource.Load(\"MyImage.jpg\"))\r\n        {\r\n            bmp.Rotate(WICBitmapTransformOptions.WICBitmapTransformRotate90);\r\n            bmp.ConvertTo(WicPixelFormat.GUID_WICPixelFormat32bppBGR); // needed to be able to work with Direct2D\r\n            using (var newBmp = new WicBitmapSource(bmp.Width, bmp.Height, WicPixelFormat.GUID_WICPixelFormat32bppPRGBA))\r\n            using (var rt = newBmp.CreateDeviceContext())\r\n            using (var fx = rt.CreateEffect(Direct2DEffects.CLSID_D2D1Grayscale))\r\n            using (var cb = rt.CreateBitmapFromWicBitmap(bmp.ComObject))\r\n            {\r\n                fx.SetInput(0, cb);\r\n                rt.BeginDraw();\r\n                rt.DrawImage(fx);\r\n                rt.EndDraw();\r\n                newBmp.Save(\"gray.jpg\");\r\n            }\r\n        }\r\n    }\r\n    \r\n## WicNetExplorer\r\nWicNetExplorer is a GUI sample program that demonstrates how to use WicNet, it's capable of loading and saving images and shows WIC information:\r\n\r\n![image](https://github.com/smourier/WicNet/assets/5328574/af1795f4-3627-4193-a849-3e2c50f87aac)\r\n\r\nWicNetExplorer demonstrates two Windows technologies for the WIC display surface:\r\n\r\n* Direct2D's `ID2D1HwndRenderTarget` interface: https://learn.microsoft.com/en-us/windows/win32/api/d2d1/nn-d2d1-id2d1hwndrendertarget\r\n* Windows Direct Composition (aka the [Visual Layer](https://learn.microsoft.com/en-us/windows/uwp/composition/visual-layer) ), through the use of `CompositionDrawingSurface` Class: https://learn.microsoft.com/en-us/uwp/api/windows.ui.composition.compositiondrawingsurface\r\n* Direct2D's PDF rendering using `PdfCreateRenderer` method (https://learn.microsoft.com/en-us/windows/win32/api/windows.data.pdf.interop/nf-windows-data-pdf-interop-pdfcreaterenderer). Ok, it's not really WIC related, but it's fun :-)\r\n\r\n## WinUI3/WinRT interop\r\nThe WinUI3Tests program demonstrates WicNet (and therefore WIC) interop with WinRT's [SoftwareBitmap](https://learn.microsoft.com/en-us/uwp/api/windows.graphics.imaging.softwarebitmap) and WinUI3:\r\n\r\n    private static SoftwareBitmap GetSoftwareBitmap(string filePath)\r\n    {\r\n        using var bmp = WicBitmapSource.Load(filePath);\r\n\r\n        // note: software bitmap doesn't seem to support color contexts\r\n        // so we must transform it ourselves, building one using pixels after color transformation\r\n        // this is the moral equivalent to WinRT's BitmapDecoder.GetPixelDataAsync (which uses Wic underneath...)\r\n        // https://learn.microsoft.com/en-us/uwp/api/windows.graphics.imaging.bitmapdecoder.getpixeldataasync\r\n        var ctx = bmp.GetColorContexts();\r\n        if (ctx.Count \u003e 0)\r\n        {\r\n            using var transformed = GetTransformed(bmp);\r\n            if (transformed != null)\r\n            {\r\n                // get pixels as an array of bytes\r\n                var bytes = transformed.CopyPixels();\r\n\r\n                // get WinRT SoftwareBitmap\r\n                var softwareBitmap = new SoftwareBitmap(\r\n                    BitmapPixelFormat.Bgra8,\r\n                    bmp.Width,\r\n                    bmp.Height,\r\n                    BitmapAlphaMode.Premultiplied);\r\n                softwareBitmap.CopyFromBuffer(bytes.AsBuffer());\r\n                return softwareBitmap;\r\n            }\r\n        }\r\n\r\n        // software bitmap doesn't support all formats\r\n        // https://learn.microsoft.com/en-us/uwp/api/windows.graphics.imaging.bitmappixelformat\r\n        // and SoftwareBitmapSource only support Bgra8...\r\n        bmp.ConvertTo(WicPixelFormat.GUID_WICPixelFormat32bppPBGRA);\r\n\r\n        // software bitmap doesn't support \"raw\" IWicBitmapSource, it wants an IWicBitmap\r\n        using var clone = bmp.Clone();\r\n        return clone.WithSoftwareBitmap(true, ptr =\u003e SoftwareBitmap.FromAbi(ptr));\r\n    }\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmourier%2Fwicnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmourier%2Fwicnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmourier%2Fwicnet/lists"}