Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .env.example

This file was deleted.

4 changes: 1 addition & 3 deletions .github/CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,4 @@ Project maintainers may remove, edit, or reject comments, commits, issues, and p

## Reporting

Report concerns privately to:

- `mratcliff1995@gmail.com`
Use GitHub's built-in content reporting tools for abusive content. For project-specific concerns, open a brief issue without including private or sensitive details so a maintainer can arrange an appropriate follow-up.
7 changes: 4 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ Thanks for improving Photo Cutter.
1. Install .NET SDK 8.x.
2. Restore packages:
```powershell
dotnet restore .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj
dotnet restore .\\solution\\ImageUiSlicer.sln
```
3. Run locally:
```powershell
dotnet run --project .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj
dotnet run --project .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release
```

## Pull request guidelines
Expand All @@ -22,7 +22,8 @@ Thanks for improving Photo Cutter.
- Update docs for any user-facing workflow changes.
- Ensure build passes before pushing:
```powershell
dotnet build .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release
dotnet build .\\solution\\ImageUiSlicer.sln -c Release
dotnet run --project .\\solution\\ImageUiSlicer.Tests\\ImageUiSlicer.Tests.csproj -c Release
```

## Commit style
Expand Down
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ body:
description: Exact clicks/inputs so we can reproduce.
placeholder: |
1. Open image ...
2. Select Polygon ...
3. Click Commit Cutout ...
2. Select Click Around ...
3. Select Save Cut-out ...
validations:
required: true
- type: input
id: version
attributes:
label: App version
description: Release version or commit hash.
placeholder: v1.0.0
placeholder: v1.2.0
- type: dropdown
id: os
attributes:
Expand Down
3 changes: 2 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Describe the change and why it is needed.

## Verification

- [ ] `dotnet build .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release` passes
- [ ] `dotnet build .\\solution\\ImageUiSlicer.sln -c Release` passes
- [ ] Regression checks pass
- [ ] Manual run tested
- [ ] Screenshots attached (if UI changed)

Expand Down
6 changes: 2 additions & 4 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ Photo Cutter currently supports the latest release on the `main` branch and late

Please do not open public issues for security vulnerabilities.

Report privately by email:

- `mratcliff1995@gmail.com`
Use [GitHub's private vulnerability reporting form](https://github.com/Awetspoon/Photo-Cutter/security/advisories/new). This keeps reports and follow-up details private until a fix is ready.

Include:

Expand All @@ -19,4 +17,4 @@ Include:
- Potential impact
- Optional proof-of-concept

We will acknowledge receipt and provide an update as soon as possible.
The project maintainers will acknowledge the report and provide an update as soon as possible.
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ jobs:
dotnet-version: 8.0.x

- name: Restore
run: dotnet restore .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj
run: dotnet restore .\\solution\\ImageUiSlicer.sln

- name: Build (Release)
run: dotnet build .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release --no-restore
run: dotnet build .\\solution\\ImageUiSlicer.sln -c Release --no-restore

- name: Test runtime workflows
run: dotnet run --project .\\solution\\ImageUiSlicer.Tests\\ImageUiSlicer.Tests.csproj -c Release --no-build
63 changes: 38 additions & 25 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag (example: v1.0.0)'
required: true
type: string

permissions:
contents: write
Expand All @@ -30,41 +24,60 @@ jobs:
- name: Resolve release tag
id: tag
shell: pwsh
env:
RELEASE_TAG: ${{ github.ref_name }}
run: |
if ("${{ github.ref_type }}" -eq "tag") {
$tag = "${{ github.ref_name }}"
}
else {
$tag = "${{ inputs.tag }}"
$tag = $env:RELEASE_TAG
if ($tag -notmatch '^v(?<version>\d+\.\d+\.\d+)$') {
throw "Release tag must use full semantic versioning (example: v1.2.0)."
}

if ([string]::IsNullOrWhiteSpace($tag)) {
throw "Release tag is required."
}
"tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"version=$($Matches['version'])" | Out-File -FilePath $env:GITHUB_OUTPUT -Append

if (-not $tag.StartsWith("v")) {
throw "Release tag must start with 'v' (example: v1.0.0)."
}
- name: Restore solution
run: dotnet restore .\\solution\\ImageUiSlicer.sln

"tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
- name: Build solution
run: dotnet build .\\solution\\ImageUiSlicer.sln -c Release --no-restore

- name: Restore
run: dotnet restore .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj
- name: Run regression checks
run: dotnet run --project .\\solution\\ImageUiSlicer.Tests\\ImageUiSlicer.Tests.csproj -c Release --no-build

- name: Publish single-file executable
run: dotnet publish .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true /p:EnableCompressionInSingleFile=true /p:DebugType=None /p:DebugSymbols=false
run: dotnet publish .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true /p:EnableCompressionInSingleFile=true /p:DebugType=None /p:DebugSymbols=false /p:Version=${{ steps.tag.outputs.version }} /p:AssemblyVersion=${{ steps.tag.outputs.version }}.0 /p:FileVersion=${{ steps.tag.outputs.version }}.0 /p:InformationalVersion=${{ steps.tag.outputs.version }}

- name: Prepare release assets
- name: Prepare verified release assets and notes
shell: pwsh
env:
RELEASE_TAG: ${{ steps.tag.outputs.tag }}
run: |
New-Item -ItemType Directory -Force .\\release-assets | Out-Null
Copy-Item .\\solution\\ImageUiSlicer\\bin\\Release\\net8.0-windows\\win-x64\\publish\\ImageUiSlicer.exe .\\release-assets\\PhotoCutter.exe -Force
$publishedApp = '.\\solution\\ImageUiSlicer\\bin\\Release\\net8.0-windows\\win-x64\\publish\\ImageUiSlicer.exe'
$releaseApp = '.\\release-assets\\PhotoCutter.exe'
if (-not (Test-Path -LiteralPath $publishedApp)) {
throw "Published executable was not found: $publishedApp"
}

Copy-Item -LiteralPath $publishedApp -Destination $releaseApp -Force
$hash = (Get-FileHash -LiteralPath $releaseApp -Algorithm SHA256).Hash.ToLowerInvariant()
"$hash PhotoCutter.exe" | Set-Content -LiteralPath '.\\release-assets\\PhotoCutter.exe.sha256' -Encoding ascii

$releaseNotes = ".\\docs\\releases\\$env:RELEASE_TAG.md"
if (-not (Test-Path -LiteralPath $releaseNotes)) {
throw "Release notes were not found: $releaseNotes"
}

Copy-Item -LiteralPath $releaseNotes -Destination '.\\release-assets\\release-notes.md' -Force

- name: Publish GitHub release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
with:
tag_name: ${{ steps.tag.outputs.tag }}
name: Photo Cutter ${{ steps.tag.outputs.tag }}
generate_release_notes: true
body_path: release-assets/release-notes.md
fail_on_unmatched_files: true
make_latest: true
files: |
release-assets/PhotoCutter.exe
release-assets/PhotoCutter.exe.sha256
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
**/bin/
**/obj/

# Local SDK/NuGet caches
.dotnet/
.dotnet-cli/
.nuget/
# Local SDK/NuGet caches and agent workspaces
/.agents/
/.audit*/
/.dotnet*/
/.nuget/

# Visual Studio / Rider / VS Code
.vs/
Expand Down Expand Up @@ -38,7 +39,6 @@ Desktop.ini
# Environment and secrets
.env
.env.*
!.env.example

# Publish artifacts
publish/
Expand Down
103 changes: 42 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,71 @@
# Photo Cutter
# Photo Cutter

[![Release](https://img.shields.io/github/v/release/Awetspoon/Photo-Cutter?display_name=release)](https://github.com/Awetspoon/Photo-Cutter/releases/latest)
[![Build](https://img.shields.io/github/actions/workflow/status/Awetspoon/Photo-Cutter/ci.yml?branch=main&label=build)](https://github.com/Awetspoon/Photo-Cutter/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/Platform-Windows%2010%2F11-0078D6)](https://github.com/Awetspoon/Photo-Cutter/releases/latest)
[![Platform](https://img.shields.io/badge/Windows-10%20%7C%2011-0078D6)](https://github.com/Awetspoon/Photo-Cutter/releases/latest)

Windows desktop app for cutting transparent PNG assets from UI mockups and screenshots.
Turn screenshots and images into clean, transparent PNG cut-outs.

![Photo Cutter Wordmark](solution/ImageUiSlicer/Assets/Brand/ImageUiSlicer_Wordmark_Transparent.png)
**[Download Photo Cutter for Windows](https://github.com/Awetspoon/Photo-Cutter/releases/latest/download/PhotoCutter.exe)**

## Download
Photo Cutter is a privacy-friendly, portable Windows app. It runs as one file, needs no account, and keeps image processing on your computer.

- Latest release: [PhotoCutter.exe](https://github.com/Awetspoon/Photo-Cutter/releases/latest)
- Distribution format: single-file Windows executable (`PhotoCutter.exe`)
![Photo Cutter editor showing a cut-out workflow](docs/screenshots/photo-cutter-main.png)

## Core Features
## Make your first cut-out

- Selection tools: `Select`, `Lasso`, `Polygon`, `Shapes`
- Reusable custom shapes: save, apply, duplicate, paste
- Brush refinement (`Brush +` / `Brush -`) on active selections and cutouts
- Inspector preview with optional split compare
- Cutout Gallery for fast visual review
- Export presets, naming options, edge/outline controls
- Project save/load support (`.iusproj`)
1. Select **Open image** and choose a PNG, JPG, BMP, GIF, or WEBP file.
2. Use **Draw Around**, **Click Around**, or **Shape Cut** to outline what you want to keep.
3. Select **Save Cut-out**, give it a useful name, then export it as a transparent PNG.

## Quick Start
The labels are deliberately plain English. **Draw Around** is the freehand tool, while **Click Around** builds an outline point by point.

1. Open an image.
2. Draw a selection with `Shapes`, `Lasso`, or `Polygon`.
3. Click `Commit Cutout`.
4. Optional: save selection as reusable shape.
5. Export selected/all cutouts as PNG.
## What you can do

## Build From Source
- Cut with freehand drawing, connected points, or ready-made shapes.
- Zoom without changing the source image or exported resolution.
- Use a 5x–10x magnifier and choose the cutting-line colour for close edge work.
- Switch between smooth enlarged viewing and exact-pixel viewing.
- Save an exact-size reusable shape, rename it, place copies, move them, and commit each copy as a new cut-out.
- Rename and reorder committed cut-outs before exporting.
- Refine edges, compare previews, and review results in the Cut-out Gallery.
- Save a workspace and continue later without losing your cut-outs or saved shapes.
- Use the complete interface in dark or light appearance.

### Requirements
## Download and requirements

- Windows 10/11
- .NET SDK 8.0.124+ (see `global.json`)
- Windows 10 or Windows 11, 64-bit.
- One portable `PhotoCutter.exe`; no separate .NET installation is required.
- Input: PNG, JPG/JPEG, BMP, GIF, and WEBP.
- Output: transparent PNG files at the intended source-image geometry.

### Restore
Download the latest release, place `PhotoCutter.exe` wherever you prefer, and open it. The app is currently unsigned, so Windows SmartScreen may ask you to confirm the first launch. Use the SHA-256 file supplied with each release if you want to verify the download.

```powershell
dotnet restore .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj
```
## Privacy

### Run
Photo Cutter does not upload your images and does not require an account. Cutting, previews, workspaces, and exports are handled locally on your PC.

```powershell
dotnet run --project .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj
```
## Help and updates

### Build

```powershell
dotnet build .\\solution\\ImageUiSlicer\\ImageUiSlicer.csproj -c Release
```
- [Download the latest release](https://github.com/Awetspoon/Photo-Cutter/releases/latest)
- [Read what changed](docs/CHANGELOG.md)
- [Report a problem or request an improvement](https://github.com/Awetspoon/Photo-Cutter/issues)
- [Report a security issue privately](https://github.com/Awetspoon/Photo-Cutter/security/advisories/new)

## Releasing
## Build from source

Tag and push a semantic version to publish a GitHub Release:
You need Windows and the .NET 8 SDK. From the repository folder:

```powershell
git tag v1.1.1
git push origin v1.1.1
dotnet restore ".\solution\ImageUiSlicer.sln"
dotnet build ".\solution\ImageUiSlicer.sln" -c Release --no-restore
dotnet run --project ".\solution\ImageUiSlicer.Tests\ImageUiSlicer.Tests.csproj" -c Release --no-build
dotnet run --project ".\solution\ImageUiSlicer\ImageUiSlicer.csproj" -c Release
```

Release workflow uploads one asset: `PhotoCutter.exe`.

Detailed process: [docs/RELEASE.md](docs/RELEASE.md)

## Repository Structure

```text
.github/ # workflows, templates, community standards
docs/ # release guide, changelog, specs, archives
solution/ImageUiSlicer/ # WPF app source and assets
```

## Project Standards

- Contributing: [.github/CONTRIBUTING.md](.github/CONTRIBUTING.md)
- Security: [.github/SECURITY.md](.github/SECURITY.md)
- Changelog: [docs/CHANGELOG.md](docs/CHANGELOG.md)
- Code of conduct: [.github/CODE_OF_CONDUCT.md](.github/CODE_OF_CONDUCT.md)
Developer references: [architecture](docs/ARCHITECTURE.md), [behaviour contract](docs/BEHAVIOR_CONTRACT.md), [contributing](.github/CONTRIBUTING.md), and [release process](docs/RELEASE.md).

## License

MIT. See [LICENSE](LICENSE).
Photo Cutter is available under the [MIT License](LICENSE).
Loading
Loading