{"id":30838996,"url":"https://github.com/happybono/sharedmemorysample","last_synced_at":"2025-09-13T03:04:22.809Z","repository":{"id":313486686,"uuid":"1051593588","full_name":"happybono/SharedMemorySample","owner":"happybono","description":"Two WinForms applications that exchange an image across processes using a named MemoryMappedFile and a named AutoReset event. Image data is handled with OpenCvSharp and displayed in PictureBox controls.","archived":false,"fork":false,"pushed_at":"2025-09-06T10:37:04.000Z","size":47,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-06T12:22:55.860Z","etag":null,"topics":["csharp","hidpi","hidpi-screen","memorymappedfile","netframework","netframework48","opencv","opencvsharp","processes","sharedmemory","sharedmemoryexample"],"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/happybono.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-06T10:19:42.000Z","updated_at":"2025-09-06T10:47:46.000Z","dependencies_parsed_at":"2025-09-06T12:22:58.936Z","dependency_job_id":"f24f9054-7106-49ab-bc6d-4c3a8c0c2858","html_url":"https://github.com/happybono/SharedMemorySample","commit_stats":null,"previous_names":["happybono/sharedmemorysample"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/happybono/SharedMemorySample","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happybono%2FSharedMemorySample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happybono%2FSharedMemorySample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happybono%2FSharedMemorySample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happybono%2FSharedMemorySample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/happybono","download_url":"https://codeload.github.com/happybono/SharedMemorySample/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/happybono%2FSharedMemorySample/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274389539,"owners_count":25276358,"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","status":"online","status_checked_at":"2025-09-09T02:00:10.223Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","hidpi","hidpi-screen","memorymappedfile","netframework","netframework48","opencv","opencvsharp","processes","sharedmemory","sharedmemoryexample"],"created_at":"2025-09-06T18:14:44.119Z","updated_at":"2025-09-12T02:02:19.408Z","avatar_url":"https://github.com/happybono.png","language":"C#","readme":"# SharedMemorySample\nTwo WinForms applications that exchange an image across processes using a named MemoryMappedFile and a named AutoReset event. Image data is handled with OpenCvSharp and displayed in PictureBox controls.\n\n- .NET target : .NET Framework 4.8\n- Language : C# 7.3\n- UI : Windows Forms (WinForms)\n- Libraries : OpenCvSharp, OpenCvSharp.Extensions\n\nProjects :\n- SharedMemorySender (namespace : SharedMemoryTest)\n- SharedMemoryReceiver (namespace : SharedMemoryReceiver)\n\n## How it works\nThe sender loads an image into an OpenCvSharp `Mat`, writes a small header followed by the raw pixel bytes to a named memory-mapped file, then signals a named event. The receiver waits on the event, reads the header and data from the same memory, reconstructs the `Mat`, and displays it.\n\nNamed objects (must match exactly in both apps) :\n- Memory-mapped file name : `SharedMemoryTest`\n- Event name : `SharedMemoryTest_ImageReady`\n\nShared memory layout (byte offsets) :\n- Header (5 x 32-bit integers, 20 bytes total)\n  1. type    (int) OpenCV Mat type (e.g., CV_8UC3), written as `mat.Type()`\n  2. step    (int) stride in bytes per row, written as `(int)mat.Step()`\n  3. width   (int) `mat.Cols`\n  4. height  (int) `mat.Rows`\n  5. dataSize(int) total raw byte size = `mat.Total() * mat.ElemSize()`\n- Pixel data (`dataSize` bytes) : raw copy of `mat.Data`\n\nMemory limits :\n- Sender allocates 100 MB for the shared memory.\n- Sender rejects images if `HeaderSize + dataSize \u003e 100 MB`.\n- Receiver rejects payloads if width \u003c= 0, height \u003c= 0, dataSize \u003c= 0, or dataSize \u003e 90 MB.\n\nNote : Data is uncompressed raw bytes; the receiver constructs the Mat with `new Mat(height, width, (MatType)type)` and copies the bytes into it.\n\n## Requirements\n- Windows with .NET Framework 4.8\n- Visual Studio 2022\n- NuGet packages :\n  - OpenCvSharp\n  - OpenCvSharp.Extensions\n\n## Build\n1. Open the solution in Visual Studio 2022.\n2. Restore NuGet packages (e.g., from Solution Explorer or the __Manage NuGet Packages__ UI).\n3. Build the solution (__Build__).\n\nBoth projects are WinForms apps targeting .NET Framework 4.8.\n\n## Run\nYou need both apps running to see inter-process image transfer.\n\nOrder considerations :\n- Sender creates or opens the shared memory and event on startup.\n- Receiver opens existing objects only when you click Start. If the sender has not created them yet, Start will fail with \"Start failed  : ...\".\n- Practical guidance : Start the sender first, or start the receiver but click Start only after the sender has launched.\n\n### SharedMemorySender (FrmSender)\n\nControls :\n- Load image (btnLoad)\n- Show image (btnShow)\n- PictureBox (630 x 420, StretchImage)\n- StatusStrip (RoyalBlue) with labels :\n  - Status, Width, Height, Type, Size, KB Step\n\nBehavior :\n- Load image :\n  - Opens a file dialog filtered to : `*.jpg;*.jpeg;*.jpe;*.jfif;*.png;*.tif;*.bmp`\n  - Loads the file with `ImreadModes.Unchanged` into `Mat`.\n  - Calculates header values :\n    - `type = mat.Type()`\n    - `step = (int)mat.Step()`\n    - `width = mat.Cols`\n    - `height = mat.Rows`\n    - `dataSize = (int)(mat.Total() * mat.ElemSize())`\n  - Writes header + data to the memory-mapped file (offset 0 for header, then pixels).\n  - Flushes the accessor and signals the event.\n  - Updates UI :\n    - Displays the loaded image in the sender’s PictureBox.\n    - Status text set to \"Image loaded\".\n    - Width / Height / Type / KB Step shown from header.\n    - Size label shows `dataSize  /  1024` (numeric value, no \"KB\" suffix).\n  - If the image does not fit : sets Status to \"Image too large for shared memory.\" and aborts.\n\n- Show image :\n  - Reads back the current header and data from the same shared memory (local verification).\n  - Reconstructs a `Mat` from the memory and displays it locally.\n- Form close : disposes the event and memory-mapped file.\n\nDPI handling :\n- On Load, measures current DPI and sets the Status label width to a DPI-scaled value (approx. 630 px at 100% scaling).\n\n### SharedMemoryReceiver (FrmReceiver)\nControls :\n- Start (btnStart)\n- Stop (btnStop)\n- Save Image (btnSave)\n- Clear (btnClear)\n- Oneshot Mode (chkOneShot)\n- PictureBox (630 x 420, StretchImage)\n- StatusStrip (green) with labels :\n  - Status, Width, Height, Type, Size, KB Step\n\nBehavior :\n- Start :\n  - Opens existing memory-mapped file for read and existing event.\n  - Sets \"one-shot\" mode based on checkbox.\n  - Disables Start and checkbox; Stop is disabled in one-shot mode and enabled otherwise.\n  - Status label width is set to a small or large size depending on whether an image is already displayed, then text set to \"Waiting (one shot)\" or \"Waiting for images...\".\n  - Starts a background receive loop.\n\n- Receive loop :\n  - Waits up to 500 ms for the event. On signal, reads the header and data.\n  - Validates header and data size (width, height, 0 \u003c dataSize ≤ 90 MB).\n  - Constructs a `Mat`, copies bytes, replaces the current Mat under a lock.\n  - On UI thread :\n    - Converts to `Bitmap` and displays in PictureBox.\n    - Enables Save.\n    - Updates Width / Height / Type / KB Step / Size (Size shows `\u003cKB\u003e KB` with unit).\n  - In one-shot mode, stops after the first image and sets Status to \"One shot received\".\n\n- Stop :\n  - Stops receiving; re-enables Start and checkbox; sets Status to \"Stopped\".\n\n- Save Image :\n  - Clones the current Mat under a lock and opens a SaveFileDialog :\n    - Filter : PNG / JPEG / BMP / TIFF\n    - Default filename : `received.png`\n  - Saves with `Mat.SaveImage()`. On success, Status set to \"Saved : \u003cpath\u003e\". On failure, Status set to \"Save failed : \u003cmessage\u003e\".\n\n- Clear :\n  - Disposes current Mat and clears the PictureBox.\n  - Disables Save.\n  - Status set to \"Cleared\".\n\n- Error handling :\n  - Any read / display errors set Status accordingly (e.g., \"Invalid header\", \"Error : ...\", \"Display failed  : ...\").\n\nDPI handling :\n- On Load and on DPI change (DpiChanged, DpiChangedBeforeParent, DpiChangedAfterParent), measures current DPI and updates internal DPI values.\n- The Status label width is toggled between two DPI-scaled widths (approx. 130 px for compact and 630 px for expanded) depending on context.\n\nCleanup :\n- The receiver defines a `Form1_FormClosed` method that stops the loop and disposes resources (event, memory, Mat). The DPI change events are wired; the FormClosed handler is defined in code but is not wired in the designer.\n\n## Protocol details (exact values from code)\nConstants :\n- Memory-mapped file name : `SharedMemoryTest`\n- Event name : `SharedMemoryTest_ImageReady`\n- Sender shared memory size : `100 * 1024 * 1024` bytes\n- HeaderIntCount : `5`\n- HeaderSize : `sizeof(int) * 5` (20 bytes)\n\nSender writes :\n- Header : `{ type, step, width, height, dataSize }`\n- Data : `byte[dataSize]` copied from `mat.Data`\n\nReceiver reconstructs :\n- `new Mat(height, width, (MatType)type)`\n- `Marshal.Copy(buffer, 0, mat.Data, dataSize)`\n\nField meanings as displayed in the UI :\n- Type : raw OpenCV Mat type integer (`Mat.Type()`)\n- KB Step : row stride in bytes (`(int)mat.Step()`)\n- Size : in KB; receiver shows with \" KB\" suffix; sender shows number only\n- Width / Height : in pixels\n\n## Notes and limitations\n- Single payload buffer; each new image overwrites the previous content.\n- No versioning; both processes must agree on the header format.\n- The receiver ignores `step` for reconstruction and assumes the provided buffer fits `height * width * elemSize`.\n- The event is AutoReset; one waiting receiver is released per signal.\n- The receiver enforces a stricter dataSize upper bound (90 MB) than the sender’s allocation (100 MB).\n\n## UI reference\nSharedMemorySender :\n- **Buttons** : Load image, Show image\n- **PictureBox** : shows the loaded or read-back image\n- **Status** : \"Image loaded\", errors like \"Image too large for shared memory.\"\n- **Status strip color** : RoyalBlue\n\nSharedMemoryReceiver :\n- **Buttons** : Start, Stop, Save Image, Clear\n- **Checkbox** : Oneshot Mode\n- **PictureBox** : shows the received image\n- **Status** : \"Waiting for images...\", \"Waiting (one shot)\", \"One shot received\", \"Stopped\", \"Cleared\", failures as described\n- **Status strip color** : green\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhappybono%2Fsharedmemorysample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhappybono%2Fsharedmemorysample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhappybono%2Fsharedmemorysample/lists"}