{"id":28763529,"url":"https://github.com/ghackenberg/terminalpaint","last_synced_at":"2026-05-07T14:43:33.468Z","repository":{"id":296851126,"uuid":"991916398","full_name":"ghackenberg/TerminalPaint","owner":"ghackenberg","description":"A basic paint application entirely running the the terminal and written in C#.","archived":false,"fork":false,"pushed_at":"2025-06-02T12:07:28.000Z","size":908,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-03T00:00:55.757Z","etag":null,"topics":["csharp","dotnet","paint","terminal"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghackenberg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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,"zenodo":null}},"created_at":"2025-05-28T10:43:30.000Z","updated_at":"2025-06-02T12:07:31.000Z","dependencies_parsed_at":"2025-06-03T00:01:09.645Z","dependency_job_id":"26e2c7ab-da3e-4a37-937e-d6db2213c763","html_url":"https://github.com/ghackenberg/TerminalPaint","commit_stats":null,"previous_names":["ghackenberg/terminalpaint"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ghackenberg/TerminalPaint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghackenberg%2FTerminalPaint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghackenberg%2FTerminalPaint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghackenberg%2FTerminalPaint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghackenberg%2FTerminalPaint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghackenberg","download_url":"https://codeload.github.com/ghackenberg/TerminalPaint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghackenberg%2FTerminalPaint/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260326777,"owners_count":22992387,"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","dotnet","paint","terminal"],"created_at":"2025-06-17T09:09:43.998Z","updated_at":"2025-10-25T20:11:15.658Z","avatar_url":"https://github.com/ghackenberg.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🖼️ TerminalPaint\n\n**TerminalPaint** is a basic paint application running in the terminal.\nThe application features a color picker, rectangle and line drawing tools, as well as loading and saving of images.\nThe color picker provides access to a small palette of colors supported on a wide range of platforms (e.g. Windows, Linux, and MacOS).\nThe line drawing tool uses a simple implementation of the Bresenham algorithm for line discretization.\nAnd image loading and saving uses a custom image format, which intentionally is not compatible with other tools.\n\nWe use this application for teaching programming at the [School of Engineering](https://fh-ooe.at/en/campus-wels) of the [University of Applied Sciences Upper Austria](https://fh-ooe.at/en).\nAccording to our experience, the application is simple enough to be fully unterstood even by beginners, but interesting enough to motivate students to work on the assigments.\n\n*Enjoy! 😉*\n\n## Screencasts\n\nHere are some screencasts showing **TerminalPaint** in action:\n\n![](./Screencasts/Rectangles%20and%20Fill.gif)\n\n## Lessons\n\nWe use the **TerminalPaint** application to teach the following lessons:\n\n- 📖 [**Lesson 0: Console basics**](./Lessons/Lesson_00/README.md) - Working with the *C# Console API*.\n- 📖 [**Lesson 1: Pointer navigation**](./Lessons/Lesson_01//README.md) - Moving the pointer with the arrow keys.\n- 📖 [**Lesson 2: Image representation**](./Lessons/Lesson_02/README.md) - Representing images in computer memory.\n- 📖 [**Lesson 3: Color selection**](./Lessons/Lesson_03/README.md) - Implementing a color picking feature.\n- 📖 [**Lesson 4: Clear operation**](./Lessons/Lesson_04/README.md) - Clearing the entire image.\n- 📖 [**Lesson 5: Fill operation**](./Lessons/Lesson_05/README.md) - Filling image regions with a new color.\n- 📖 [**Lesson 6: Rectangle operation**](./Lessons/Lesson_06/README.md) - Implementing a rectangle drawing tool.\n- 📖 [**Lesson 7: Line operation**](./Lessons/Lesson_07/README.md) - Implementing a line drawing tool.\n- 📖 [**Lesson 8: Storage operation**](./Lessons/Lesson_08/README.md) - Storing images to and loading images from disk.\n- 📖 [**Lesson 9: Outlook**](./Lessons/Lesson_09/README.md) - Where you can go from here.\n\n## Drawings\n\nHere are some drawings made with **TerminalPaint**:\n\n\u003cimg src=\"./Drawings/Flower%20Heart%20with%20Textbars.png\" width=\"50%\"/\u003e\u003cimg src=\"./Drawings/Rocket%20with%20Color%20Picker.png\" width=\"50%\"/\u003e\n\u003cimg src=\"./Drawings/Rectangles%20and%20Lines.png\" width=\"50%\"/\u003e\u003cimg src=\"./Drawings/Man%20with%20Hat.png\" width=\"50%\"/\u003e\n\n## Details\n\nHere is an overview of the classes including their fields, methods, and dependencies:\n\n```mermaid\nclassDiagram\n    class Program {\n        Main() void$\n    }\n\n    class Tool {\n        \u003c\u003cabstract\u003e\u003e\n    }\n    class Color {\n        current: ConsoleColor$\n        PaintPalette() void$\n        Change(delta: int) void$\n    }\n    class Pointer {\n        currentX: int$\n        currentY: int$\n        Move(dx: int, dy: int) void$\n        Brush() void$\n    }\n    class Clear {\n        Execute() void$\n    }\n    class Fill {\n        Execute() void$\n    }\n    class Rectangle {\n        -startX: int$\n        -startY: int$\n        Execute() void$\n        -Move(dx: int, dy: int) void$\n        -Commit() void$\n        -Cancel() void$\n    }\n    class Line {\n        -startX: int$\n        -startY: int$\n        Execute() void$\n        -Move(dx: int, dy: int) void$\n        -Commit() void$\n        -Cancel() void$\n    }\n    class Open {\n        Execute() void$\n    }\n    class Save {\n        Execute() void$\n    }\n\n    class Core {\n        \u003c\u003cabstract\u003e\u003e\n    }\n    class Image {\n        width: int$\n        height: int$\n        size: int = width * height$\n        data: ConsoleColor[]$\n        Paint() void$\n    }\n    class Util {\n        borderTop: int$\n        borderLeft: int$\n        borderRight: int$\n        borderBottom: int$\n        PaintFrame() void$\n        PaintBorderTop() void$\n        PaintBorderLeft() void$\n        PaintBorderRight() void$\n        PaintBorderBottom() void$\n        PaintTextTop() void$\n        PaintTextBottom() void$\n        ReadBool() bool$\n        ReadFileName(exists: bool) string$\n    }\n\n    Program ..\u003e Tool: calls\n\n    Tool \u003c|-- Color: is a\n    Tool \u003c|-- Pointer: is a\n    Tool \u003c|-- Clear: is a\n    Tool \u003c|-- Fill: is a\n    Tool \u003c|-- Rectangle: is a\n    Tool \u003c|-- Line: is a\n    Tool \u003c|-- Open: is a\n    Tool \u003c|-- Save: is a\n\n    Color ..\u003e Core: uses\n    Pointer ..\u003e Core: uses\n    Clear ..\u003e Core: uses\n    Fill ..\u003e Core: uses\n    Rectangle ..\u003e Core: uses\n    Line ..\u003e Core: uses\n    Open ..\u003e Core: uses\n    Save ..\u003e Core: uses\n\n    Core \u003c|-- Image: is a\n    Core \u003c|-- Util: is a\n\n```\n\n## Documents\n\nFinally, here are the standard documents shipped with open source software:\n\n* 📄 [**LICENSE.md**](./LICENSE.md) - Explains the license of the source code.\n* 📄 [**CHANGELOG.md**](./CHANGELOG.md) - Summarizes major changes to the source code.\n* 📄 [**CONTRIBUTING.md**](./CONTRIBUTING.md) - Defines guidelines for contributing to the source code. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghackenberg%2Fterminalpaint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghackenberg%2Fterminalpaint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghackenberg%2Fterminalpaint/lists"}