{"id":23193538,"url":"https://github.com/mcraiha/csharp-dithering","last_synced_at":"2025-04-03T03:09:28.058Z","repository":{"id":36370410,"uuid":"40675253","full_name":"mcraiha/CSharp-Dithering","owner":"mcraiha","description":"CSharp (C#) versions of certain dithering algorithms","archived":false,"fork":false,"pushed_at":"2025-02-10T18:21:40.000Z","size":908,"stargazers_count":24,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T23:09:12.880Z","etag":null,"topics":["csharp","dithering-methods","dotnet","net8","netstandard20"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcraiha.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGE-LOG.md","contributing":null,"funding":null,"license":null,"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":"2015-08-13T18:31:27.000Z","updated_at":"2025-03-12T05:43:58.000Z","dependencies_parsed_at":"2024-11-22T21:57:51.278Z","dependency_job_id":null,"html_url":"https://github.com/mcraiha/CSharp-Dithering","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcraiha%2FCSharp-Dithering","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcraiha%2FCSharp-Dithering/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcraiha%2FCSharp-Dithering/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcraiha%2FCSharp-Dithering/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcraiha","download_url":"https://codeload.github.com/mcraiha/CSharp-Dithering/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246927835,"owners_count":20856198,"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":["csharp","dithering-methods","dotnet","net8","netstandard20"],"created_at":"2024-12-18T13:11:45.633Z","updated_at":"2025-04-03T03:09:28.030Z","avatar_url":"https://github.com/mcraiha.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CSharp-Dithering\nCSharp (C#) versions of certain dithering algorithms. This project is .NET 8 compatible, managed and available as Nuget!\n\n## Build status\n![](https://github.com/mcraiha/CSharp-Dithering/workflows/.NET%20Core/badge.svg)\n\n## Nuget\n[![Nuget](https://img.shields.io/badge/Nuget-CSharpDithering-blue)](https://www.nuget.org/packages/LibDithering/)\n\n## Projects using this library\n[Dithery-cli](https://github.com/mcraiha/Dithery-cli)\n[Dithery](https://github.com/mcraiha/Dithery)\n\n## Introduction to this project\nThis project contains implementations of different dithering algorithms (C#). They can be used with any graphics/image API.\n\n## Introduction to dithering\nAs [Wikipedia](https://en.wikipedia.org/wiki/Dither) says *\"Dither is an intentionally applied form of noise used to randomize quantization error, preventing large-scale patterns such as color banding in images.\"*\n\nIn this case dithering is used help in color reduction (less banding). This reduction of colors + dithering combo can be used e.g. to reduce file sizes, make artsy images and avoid issues when displaying images on displays that have limited color range.\n\n## Implementation\nInspiration for this project came from [blog post](http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/) made by **Tanner Helland**.\n\n[DitheringBase.cs](https://github.com/mcraiha/CSharp-Dithering/blob/master/src/DitheringBase.cs) contains the abstract base class that every error pushing dithering implmentation should use.\n\n[FakeDithering.cs](https://github.com/mcraiha/CSharp-Dithering/blob/master/src/FakeDithering.cs) is \"fake\" dithering since it doesn't do any dithering. It is used to get image with reduced colors.\n\nOther .cs files are used for different dithering algorithms, and the files are named as **SomeAlgorithm**Dithering.cs\n\n[Samples folder](https://github.com/mcraiha/CSharp-Dithering/blob/master/samples) contains images that are shown in the end of this Readme file\n\n## Examples\n\nUse Atkinson dithering with web safe color reduction for 24 bit PNG input with System.Drawing (this example is Windows only)\n\n```cs\npublic void DoAtkinsonDithering()\n{\n    AtkinsonDitheringRGB\u003cbyte\u003e atkinson = new AtkinsonDitheringRGB\u003cbyte\u003e(TrueColorBytesToWebSafeColorBytes);\n\n    using(FileStream pngStream = new FileStream(\"half.png\", FileMode.Open, FileAccess.Read))\n    using(var image = new Bitmap(pngStream))\n    {\n        byte[,,] bytes = ReadBitmapToColorBytes(image);\n\n        TempByteImageFormat temp = new TempByteImageFormat(bytes);\n        atkinson.DoDithering(temp);\n\n        WriteToBitmap(image, temp.GetPixelChannels);\n\n        image.Save(\"test.png\");\n    }\n}\n\nprivate static void TrueColorBytesToWebSafeColorBytes(in byte[] input, ref byte[] output)\n{\n    for (int i = 0; i \u003c input.Length; i++)\n    {\n        output[i] = (byte)(Math.Round(input[i] / 51.0) * 51);\n    }\n}\n\nprivate static byte[,,] ReadBitmapToColorBytes(Bitmap bitmap)\n{\n    byte[,,] returnValue = new byte[bitmap.Width, bitmap.Height, 3];\n    for (int x = 0; x \u003c bitmap.Width; x++)\n    {\n        for (int y = 0; y \u003c bitmap.Height; y++)\n        {\n            Color color = bitmap.GetPixel(x, y);\n            returnValue[x, y, 0] = color.R;\n            returnValue[x, y, 1] = color.G;\n            returnValue[x, y, 2] = color.B;\n        }\n    }\n    return returnValue;\n}\n\nprivate static void WriteToBitmap(Bitmap bitmap, Func\u003cint, int, byte[]\u003e reader)\n{\n    for (int x = 0; x \u003c bitmap.Width; x++)\n    {\n        for (int y = 0; y \u003c bitmap.Height; y++)\n        {\n            byte[] read = reader(x, y);\n            Color color = Color.FromArgb(read[0], read[1], read[2]);\n            bitmap.SetPixel(x, y, color);\n        }\n    }\n}\n```\n## Usage\n\nYou have to always give color reduction method as parameter for dither constructor. You can dither multiple images with one instance by calling DoDithering again with different input.\n\n## Wasn't this .NET Framework project?\n\nYes, but time moves on...\n\n## License\n\nText in this document and source code files are released into the public domain. See [PUBLICDOMAIN](https://github.com/mcraiha/CSharp-Dithering/blob/master/PUBLICDOMAIN) file.\n\nParrot image (half.png) is made from image that comes from [Kodak Lossless True Color Image Suite](http://r0k.us/graphics/kodak/) and it doesn't have any specific license.\n\n## Samples\n\nI took the famous [parrot image](http://r0k.us/graphics/kodak/kodim23.html) and reduced its size. Then I ran the image (which has 64655 different colors) with all dithering methods and using [Web safe colors](https://en.wikipedia.org/wiki/Web_colors#Web-safe_colors) as palette (216 colors). \n\n![Original](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/half.png)\n\nOriginal\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Floyd-Steinberg](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_FS.png)\n\nFloyd-Steinberg\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Jarvis-Judice-Ninke](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_JJN.png)\n\nJarvis-Judice-Ninke\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Stucki](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_STU.png)\n\nStucki\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Atkinson](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_ATK.png)\n\nAtkinson\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Burkes](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_BUR.png)\n\nBurkes\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Sierra](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_SIE.png)\n\nSierra\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Sierra Two Row](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_SIE2R.png)\n\nSierra Two Row\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![Sierra Lite](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_SIEL.png)\n\nSierra Lite\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n![None](https://github.com/mcraiha/CSharp-Dithering/blob/master/Samples/dither_NONE.png)\n\nNo dithering, just color reduction\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcraiha%2Fcsharp-dithering","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcraiha%2Fcsharp-dithering","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcraiha%2Fcsharp-dithering/lists"}