├── src ├── GlobalSuppressions.cs ├── Resources │ ├── Icons │ │ ├── ResetIcon-120.png │ │ ├── ResetIcon-144.png │ │ ├── ResetIcon-192.png │ │ ├── ResetIcon-384.png │ │ ├── ResetIcon-96.png │ │ ├── ContentAwareFill-120.png │ │ ├── ContentAwareFill-144.png │ │ ├── ContentAwareFill-192.png │ │ ├── ContentAwareFill-384.png │ │ └── ContentAwareFill-96.png │ └── src │ │ ├── Readme.txt │ │ ├── ResetIcon.svg │ │ └── ContentAwareFill.svg ├── IgnoredWords.dic ├── PaintDotNet │ ├── VisualStyleClass.cs │ ├── EtchedLine.cs │ ├── UI.cs │ └── HeaderLabel.cs ├── SampleSource.cs ├── FillDirection.cs ├── ContentAwareFill.sln ├── Resynthesizer │ ├── MatchContextType.cs │ ├── ResynthesizerException.cs │ ├── ResynthesizerRandom.cs │ ├── PointExtensions.cs │ ├── PointCollectionUtil.cs │ ├── ResynthesizerConstants.cs │ ├── Comparers │ │ ├── VerticalPointComparer.cs │ │ ├── HorizontalPointComparer.cs │ │ └── DirectionalPointComparer.cs │ ├── PointIndexedArray.cs │ ├── PointIndexedBitArray.cs │ └── TargetPointSorter.cs ├── DebugUtil.cs ├── .editorconfig ├── PluginIconUtil.cs ├── Collections │ ├── ImmutablePooledList_1.cs │ └── NativeArray_1.cs ├── PluginSupportInfo.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── ContentAwareFillConfigToken.cs ├── BitmapUtil.cs ├── ContentAwareFill.csproj ├── PluginThemingUtil.cs ├── ContentAwareFillConfigDialog.resx ├── ContentAwareFillEffect.cs ├── ResynthesizerRunner.cs ├── ContentAwareFillConfigDialog.cs └── ContentAwareFillConfigDialog.Designer.cs ├── README.md ├── .gitattributes ├── Third Party Notices.txt ├── .gitignore └── License.txt /src/GlobalSuppressions.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/GlobalSuppressions.cs -------------------------------------------------------------------------------- /src/Resources/Icons/ResetIcon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ResetIcon-120.png -------------------------------------------------------------------------------- /src/Resources/Icons/ResetIcon-144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ResetIcon-144.png -------------------------------------------------------------------------------- /src/Resources/Icons/ResetIcon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ResetIcon-192.png -------------------------------------------------------------------------------- /src/Resources/Icons/ResetIcon-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ResetIcon-384.png -------------------------------------------------------------------------------- /src/Resources/Icons/ResetIcon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ResetIcon-96.png -------------------------------------------------------------------------------- /src/Resources/Icons/ContentAwareFill-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ContentAwareFill-120.png -------------------------------------------------------------------------------- /src/Resources/Icons/ContentAwareFill-144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ContentAwareFill-144.png -------------------------------------------------------------------------------- /src/Resources/Icons/ContentAwareFill-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ContentAwareFill-192.png -------------------------------------------------------------------------------- /src/Resources/Icons/ContentAwareFill-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ContentAwareFill-384.png -------------------------------------------------------------------------------- /src/Resources/Icons/ContentAwareFill-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xC0000054/pdn-content-aware-fill/HEAD/src/Resources/Icons/ContentAwareFill-96.png -------------------------------------------------------------------------------- /src/IgnoredWords.dic: -------------------------------------------------------------------------------- 1 | Aero 2 | config 3 | dest 4 | dpi 5 | github 6 | levent 7 | Namespace 8 | pdn 9 | png 10 | ptr 11 | resynthesizer 12 | Royale 13 | trys 14 | typelib 15 | Zune 16 | -------------------------------------------------------------------------------- /src/Resources/src/Readme.txt: -------------------------------------------------------------------------------- 1 | The files in this folder have been adapted from the following resources. 2 | 3 | ContentAwareFill.svg: A public domain SVG from https://freesvg.org/medical-bandage. 4 | ResetIcon.svg: Rerun_16x.svg in the Visual Studio 2017 Image Library 5 | 6 | -------------------------------------------------------------------------------- /src/PaintDotNet/VisualStyleClass.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////////// 2 | // Paint.NET // 3 | // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. // 4 | // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. // 5 | // See License-pdn.txt for full licensing and attribution // 6 | // details. // 7 | // . // 8 | ///////////////////////////////////////////////////////////////////////////////// 9 | 10 | 11 | namespace ContentAwareFill 12 | { 13 | internal enum VisualStyleClass 14 | { 15 | Classic, 16 | Luna, // also covers Royale, which is a derivative of Luna 17 | Aero, 18 | Other 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SampleSource.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | namespace ContentAwareFill 24 | { 25 | public enum SampleSource 26 | { 27 | AllAround = 0, 28 | Sides, 29 | TopAndBottom 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/FillDirection.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | namespace ContentAwareFill 24 | { 25 | public enum FillDirection 26 | { 27 | Random, 28 | InwardToCenter, 29 | OutwardFromCenter 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pdn-content-aware-fill 2 | 3 | A [Paint.NET](http://www.getpaint.net) Effect plugin that replaces the contents of the selection with pixels that are the closest match to the areas outside the selection. 4 | This is often called 'content aware fill'. 5 | 6 | This plugin is based on the GIMP [Resynthesizer](https://github.com/bootchk/resynthesizer) plugin. 7 | 8 | 9 | ## How to install the plugin 10 | 11 | 1. Exit Paint.NET. 12 | 2. Place the ContentAwareFill folder in the Paint.NET Effects folder which is usually located in one the following locations depending on the Paint.NET version you have installed. 13 | 14 | Paint.NET Version | Effects Folder Location 15 | --------|---------- 16 | Classic | C:\Program Files\Paint.NET\Effects 17 | Microsoft Store | Documents\paint.net App Files\Effects 18 | Portable | \Effects 19 | 20 | 3. Restart Paint.NET. 21 | 4. The plug-in will now be available as the Content Aware Fill menu item in the Selection category of the Paint.NET Effects menu. 22 | 23 | ## License 24 | 25 | This project is licensed under the terms of the GNU General Public License version 2.0. 26 | See [License.txt](License.txt) for more information. -------------------------------------------------------------------------------- /src/ContentAwareFill.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2037 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContentAwareFill", "ContentAwareFill.csproj", "{8DA3487E-8747-49C0-92EB-46033D4F9972}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8DA3487E-8747-49C0-92EB-46033D4F9972}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8DA3487E-8747-49C0-92EB-46033D4F9972}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8DA3487E-8747-49C0-92EB-46033D4F9972}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8DA3487E-8747-49C0-92EB-46033D4F9972}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {1E9A8990-8C46-4C13-BE8C-2E07185389DB} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/Resynthesizer/MatchContextType.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | namespace ContentAwareFill 24 | { 25 | internal enum MatchContextType 26 | { 27 | None = 0, 28 | Random = 1, 29 | InwardConcentric = 2, 30 | InwardHorizontal = 3, 31 | InwardVertical = 4, 32 | OutwardConcentric = 5, 33 | OutwardHorizontal = 6, 34 | OutwardVertical = 7, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Resynthesizer/ResynthesizerException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using System; 24 | 25 | namespace ContentAwareFill 26 | { 27 | [Serializable] 28 | internal sealed class ResynthesizerException : Exception 29 | { 30 | public ResynthesizerException(string message) : base(message) 31 | { 32 | } 33 | 34 | public ResynthesizerException(string message, Exception inner) : base(message, inner) 35 | { 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Resynthesizer/ResynthesizerRandom.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using System; 24 | using System.Runtime.CompilerServices; 25 | 26 | namespace ContentAwareFill 27 | { 28 | internal sealed class ResynthesizerRandom 29 | { 30 | private readonly Random random; 31 | 32 | public ResynthesizerRandom(int seed) 33 | { 34 | this.random = new Random(seed); 35 | } 36 | 37 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 38 | public int Next(int maxValue) => this.random.Next(maxValue); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Resynthesizer/PointExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet.Rendering; 24 | using System.Runtime.CompilerServices; 25 | 26 | namespace ContentAwareFill 27 | { 28 | internal static class PointExtensions 29 | { 30 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 | public static Point2Int32 Add(this Point2Int32 point, Point2Int32 value) 32 | { 33 | return new Point2Int32(point.X + value.X, point.Y + value.Y); 34 | } 35 | 36 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 37 | public static Point2Int32 Subtract(this Point2Int32 point, Point2Int32 value) 38 | { 39 | return new Point2Int32(point.X - value.X, point.Y - value.Y); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DebugUtil.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet.Imaging; 24 | using System.Diagnostics; 25 | using System.IO; 26 | 27 | namespace ContentAwareFill 28 | { 29 | internal static class DebugUtil 30 | { 31 | [Conditional("DEBUG")] 32 | public static void SaveBitmapAsPng(string path, IBitmapSource bitmap, IImagingFactory imagingFactory) 33 | { 34 | using (FileStream fs = new(path, FileMode.Create, FileAccess.Write)) 35 | using (IBitmapEncoder encoder = imagingFactory.CreateEncoder(fs, ContainerFormats.Png)) 36 | { 37 | IBitmapFrameEncode bitmapFrame = encoder.CreateNewFrame(out var encoderOptions); 38 | 39 | bitmapFrame.Initialize(encoderOptions); 40 | bitmapFrame.SetSize(bitmap.Size); 41 | bitmapFrame.SetPixelFormat(bitmap.PixelFormat); 42 | bitmapFrame.SetResolution(bitmap.Resolution); 43 | 44 | bitmapFrame.WriteSource(bitmap); 45 | 46 | bitmapFrame.Commit(); 47 | encoder.Commit(); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Resynthesizer/PointCollectionUtil.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet.Rendering; 24 | using System; 25 | using System.Collections.Generic; 26 | 27 | namespace ContentAwareFill 28 | { 29 | internal static class PointCollectionUtil 30 | { 31 | public static RectInt32 GetBounds(IEnumerable points) 32 | { 33 | int left = int.MaxValue; 34 | int top = int.MaxValue; 35 | int right = 0; 36 | int bottom = 0; 37 | 38 | foreach (Point2Int32 item in points) 39 | { 40 | left = Math.Min(left, item.X); 41 | top = Math.Min(top, item.Y); 42 | right = Math.Max(right, item.X); 43 | bottom = Math.Max(bottom, item.Y); 44 | } 45 | 46 | return RectInt32.FromEdges(left, top, right, bottom); 47 | } 48 | 49 | public static Point2Int32 GetCenter(IEnumerable points) 50 | { 51 | RectInt32 bounds = GetBounds(points); 52 | 53 | int centerX = ((bounds.Right - bounds.Left) / 2) + bounds.Left; 54 | int centerY = ((bounds.Bottom - bounds.Top) / 2) + bounds.Top; 55 | 56 | return new Point2Int32(centerX, centerY); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome:http://EditorConfig.org 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | [*.cs] 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | vsspell_section_id = 30a86b75973f41d3b6fe30b8f7950859 13 | vsspell_ignored_words_30a86b75973f41d3b6fe30b8f7950859 = File:IgnoredWords.dic 14 | 15 | # Disable IDE0130:Namespace does not match folder structure 16 | dotnet_diagnostic.IDE0130.severity = none 17 | 18 | # Newline settings 19 | csharp_new_line_before_open_brace = all 20 | csharp_new_line_before_else = true 21 | csharp_new_line_before_catch = true 22 | csharp_new_line_before_finally = true 23 | csharp_new_line_before_members_in_object_initializers = true 24 | csharp_new_line_before_members_in_anonymous_types = true 25 | csharp_new_line_between_query_expression_clauses = true 26 | 27 | # Expression-bodied member settings 28 | csharp_style_expression_bodied_methods = false : none 29 | csharp_style_expression_bodied_constructors = false : none 30 | csharp_style_expression_bodied_operators = false : none 31 | csharp_style_expression_bodied_properties = false : none 32 | csharp_style_expression_bodied_indexers = false : none 33 | csharp_style_expression_bodied_accessors = false : none 34 | 35 | # "This." qualifier settings 36 | dotnet_style_qualification_for_field = true : suggestion 37 | dotnet_style_qualification_for_property = true : suggestion 38 | dotnet_style_qualification_for_method = false : suggestion 39 | dotnet_style_qualification_for_event = true : suggestion 40 | 41 | # Code block settings 42 | csharp_prefer_braces = true : warning 43 | 44 | # IDE0290: Use primary constructor 45 | csharp_style_prefer_primary_constructors = false 46 | 47 | # IDE0079: Remove unnecessary suppression 48 | dotnet_diagnostic.IDE0079.severity = none 49 | -------------------------------------------------------------------------------- /src/PluginIconUtil.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using System; 24 | 25 | namespace ContentAwareFill 26 | { 27 | internal static class PluginIconUtil 28 | { 29 | private static readonly ValueTuple[] AvailableIcons; 30 | 31 | static PluginIconUtil() 32 | { 33 | AvailableIcons = new ValueTuple[] 34 | { 35 | ValueTuple.Create(96, "Resources.Icons.ContentAwareFill-96.png"), 36 | ValueTuple.Create(120, "Resources.Icons.ContentAwareFill-120.png"), 37 | ValueTuple.Create(144, "Resources.Icons.ContentAwareFill-144.png"), 38 | ValueTuple.Create(192, "Resources.Icons.ContentAwareFill-192.png"), 39 | ValueTuple.Create(384, "Resources.Icons.ContentAwareFill-384.png"), 40 | }; 41 | } 42 | 43 | public static string GetIconResourceForDpi(int dpi) 44 | { 45 | for (int i = 0; i < AvailableIcons.Length; i++) 46 | { 47 | ValueTuple icon = AvailableIcons[i]; 48 | 49 | if (icon.Item1 >= dpi) 50 | { 51 | return icon.Item2; 52 | } 53 | } 54 | 55 | return "Resources.Icons.ContentAwareFill-384.png"; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Collections/ImmutablePooledList_1.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using Collections.Pooled; 24 | using PaintDotNet; 25 | using System; 26 | using System.Collections; 27 | using System.Collections.Generic; 28 | 29 | namespace ContentAwareFill.Collections 30 | { 31 | internal sealed class ImmutablePooledList : Disposable, IReadOnlyList, IReadOnlyPooledList 32 | { 33 | private readonly PooledList pooledList; 34 | 35 | public static readonly ImmutablePooledList Empty = new([]); 36 | 37 | public ImmutablePooledList(PooledList pooledList) 38 | { 39 | this.pooledList = pooledList ?? throw new ArgumentNullException(nameof(pooledList)); 40 | } 41 | 42 | public int Count => this.pooledList.Count; 43 | 44 | public ReadOnlySpan Span => this.pooledList.Span; 45 | 46 | public T this[int index] => this.pooledList[index]; 47 | 48 | public IEnumerator GetEnumerator() => this.pooledList.GetEnumerator(); 49 | 50 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 51 | 52 | protected override void Dispose(bool disposing) 53 | { 54 | if (disposing) 55 | { 56 | this.pooledList.Dispose(); 57 | } 58 | 59 | base.Dispose(disposing); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/PluginSupportInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using System; 24 | using System.Reflection; 25 | using PaintDotNet; 26 | 27 | namespace ContentAwareFill 28 | { 29 | public sealed class PluginSupportInfo : IPluginSupportInfo 30 | { 31 | public string Author 32 | { 33 | get 34 | { 35 | return ((AssemblyCompanyAttribute)typeof(ContentAwareFillEffect).Assembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company; 36 | } 37 | } 38 | 39 | public string Copyright 40 | { 41 | get 42 | { 43 | return ((AssemblyCopyrightAttribute)typeof(ContentAwareFillEffect).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false)[0]).Copyright; 44 | } 45 | } 46 | 47 | public string DisplayName 48 | { 49 | get 50 | { 51 | return ContentAwareFillEffect.StaticName; 52 | } 53 | } 54 | 55 | public Version Version 56 | { 57 | get 58 | { 59 | return typeof(ContentAwareFillEffect).Assembly.GetName().Version; 60 | } 61 | } 62 | 63 | public Uri WebsiteUri 64 | { 65 | get 66 | { 67 | return new Uri("https://forums.getpaint.net/index.php?showtopic=112730"); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Resources/src/ResetIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 38 | 40 | 41 | 43 | image/svg+xml 44 | 46 | 47 | 48 | 49 | 50 | 54 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/Resynthesizer/ResynthesizerConstants.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * The Resynthesizer - A GIMP plug-in for resynthesizing textures 26 | * 27 | * Copyright (C) 2010 Lloyd Konneker 28 | * Copyright (C) 2000 2008 Paul Francis Harrison 29 | * Copyright (C) 2002 Laurent Despeyroux 30 | * Copyright (C) 2002 David Rodríguez García 31 | * 32 | * This program is free software; you can redistribute it and/or modify 33 | * it under the terms of the GNU General Public License as published by 34 | * the Free Software Foundation; either version 2 of the License, or 35 | * (at your option) any later version. 36 | * 37 | * This program is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 | * GNU General Public License for more details. 41 | * 42 | * You should have received a copy of the GNU General Public License 43 | * along with this program; if not, write to the Free Software 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 | * 46 | */ 47 | 48 | namespace ContentAwareFill 49 | { 50 | internal static class ResynthesizerConstants 51 | { 52 | internal const float BandFraction = 0.1F; 53 | internal const float MapMultiplier = 4.0F; 54 | internal const int MaxNeighbors = 64; 55 | internal const int MaxPasses = 6; 56 | internal const uint MaxTriesPerPixel = uint.MaxValue; 57 | internal const int MaxWeight = ushort.MaxValue; 58 | internal const float TerminateFraction = 0.1F; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using System.Reflection; 24 | using System.Resources; 25 | using System.Runtime.InteropServices; 26 | using System.Runtime.Versioning; 27 | 28 | // General Information about an assembly is controlled through the following 29 | // set of attributes. Change these attribute values to modify the information 30 | // associated with an assembly. 31 | [assembly: AssemblyTitle("Resynthesizer-based content aware fill Effect plugin for Paint.NET")] 32 | [assembly: AssemblyDescription("")] 33 | [assembly: AssemblyConfiguration("")] 34 | [assembly: AssemblyCompany("null54")] 35 | [assembly: AssemblyProduct("ContentAwareFill")] 36 | [assembly: AssemblyCopyright("Copyright © 2025 Nicholas Hayes (aka null54)")] 37 | [assembly: AssemblyTrademark("")] 38 | [assembly: AssemblyCulture("")] 39 | 40 | // Setting ComVisible to false makes the types in this assembly not visible 41 | // to COM components. If you need to access a type in this assembly from 42 | // COM, set the ComVisible attribute to true on that type. 43 | [assembly: ComVisible(false)] 44 | 45 | // The following GUID is for the ID of the typelib if this project is exposed to COM 46 | [assembly: Guid("8da3487e-8747-49c0-92eb-46033d4f9972")] 47 | 48 | [assembly: SupportedOSPlatform("windows")] 49 | 50 | [assembly: NeutralResourcesLanguage("en-US")] 51 | 52 | // Version information for an assembly consists of the following four values: 53 | // 54 | // Major Version 55 | // Minor Version 56 | // Build Number 57 | // Revision 58 | // 59 | // You can specify all the values or you can default the Build and Revision Numbers 60 | // by using the '*' as shown below: 61 | // [assembly: AssemblyVersion("1.0.*")] 62 | [assembly: AssemblyVersion("2.0.2.0")] 63 | [assembly: AssemblyFileVersion("2.0.2.0")] 64 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | 65 | # GitHub Linguist override 66 | *.cs linguist-language=C# 67 | -------------------------------------------------------------------------------- /src/Resynthesizer/Comparers/VerticalPointComparer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * The Resynthesizer - A GIMP plug-in for resynthesizing textures 26 | * 27 | * Copyright (C) 2010 Lloyd Konneker 28 | * Copyright (C) 2000 2008 Paul Francis Harrison 29 | * Copyright (C) 2002 Laurent Despeyroux 30 | * Copyright (C) 2002 David Rodríguez García 31 | * 32 | * This program is free software; you can redistribute it and/or modify 33 | * it under the terms of the GNU General Public License as published by 34 | * the Free Software Foundation; either version 2 of the License, or 35 | * (at your option) any later version. 36 | * 37 | * This program is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 | * GNU General Public License for more details. 41 | * 42 | * You should have received a copy of the GNU General Public License 43 | * along with this program; if not, write to the Free Software 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 | * 46 | */ 47 | 48 | using PaintDotNet.Rendering; 49 | using System.Collections.Generic; 50 | 51 | namespace ContentAwareFill 52 | { 53 | internal readonly struct VerticalPointComparer : IComparer 54 | { 55 | private readonly bool outward; 56 | 57 | public VerticalPointComparer(bool outward) 58 | { 59 | this.outward = outward; 60 | } 61 | 62 | public int Compare(Point2Int32 point1, Point2Int32 point2) 63 | { 64 | int point1Squared = (point1.Y * point1.Y); 65 | int point2Squared = (point2.Y * point2.Y); 66 | 67 | if (this.outward) 68 | { 69 | return point2Squared.CompareTo(point1Squared); 70 | } 71 | else 72 | { 73 | return point1Squared.CompareTo(point2Squared); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Resynthesizer/Comparers/HorizontalPointComparer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * The Resynthesizer - A GIMP plug-in for resynthesizing textures 26 | * 27 | * Copyright (C) 2010 Lloyd Konneker 28 | * Copyright (C) 2000 2008 Paul Francis Harrison 29 | * Copyright (C) 2002 Laurent Despeyroux 30 | * Copyright (C) 2002 David Rodríguez García 31 | * 32 | * This program is free software; you can redistribute it and/or modify 33 | * it under the terms of the GNU General Public License as published by 34 | * the Free Software Foundation; either version 2 of the License, or 35 | * (at your option) any later version. 36 | * 37 | * This program is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 | * GNU General Public License for more details. 41 | * 42 | * You should have received a copy of the GNU General Public License 43 | * along with this program; if not, write to the Free Software 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 | * 46 | */ 47 | 48 | using PaintDotNet.Rendering; 49 | using System.Collections.Generic; 50 | 51 | namespace ContentAwareFill 52 | { 53 | internal readonly struct HorizontalPointComparer : IComparer 54 | { 55 | private readonly bool outward; 56 | 57 | public HorizontalPointComparer(bool outward) 58 | { 59 | this.outward = outward; 60 | } 61 | 62 | public int Compare(Point2Int32 point1, Point2Int32 point2) 63 | { 64 | int point1Squared = (point1.X * point1.X); 65 | int point2Squared = (point2.X * point2.X); 66 | 67 | if (this.outward) 68 | { 69 | return point2Squared.CompareTo(point1Squared); 70 | } 71 | else 72 | { 73 | return point1Squared.CompareTo(point2Squared); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/ContentAwareFillConfigToken.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet.Effects; 24 | using PaintDotNet.Imaging; 25 | 26 | namespace ContentAwareFill 27 | { 28 | public sealed class ContentAwareFillConfigToken : EffectConfigToken 29 | { 30 | public int SampleSize 31 | { 32 | get; 33 | set; 34 | } 35 | 36 | public SampleSource SampleFrom 37 | { 38 | get; 39 | set; 40 | } 41 | 42 | public FillDirection FillDirection 43 | { 44 | get; 45 | set; 46 | } 47 | 48 | public int Seed 49 | { 50 | get; 51 | set; 52 | } 53 | 54 | public bool RenderAutomatically 55 | { 56 | get; 57 | set; 58 | } 59 | 60 | public IBitmap Output 61 | { 62 | get; 63 | set; 64 | } 65 | 66 | public ContentAwareFillConfigToken(int sampleSize, 67 | SampleSource sampleFrom, 68 | FillDirection fillDirection, 69 | int seed, 70 | bool renderAutomatically, 71 | IBitmap output) 72 | { 73 | this.SampleSize = sampleSize; 74 | this.SampleFrom = sampleFrom; 75 | this.FillDirection = fillDirection; 76 | this.Seed = seed; 77 | this.RenderAutomatically = renderAutomatically; 78 | this.Output = output; 79 | } 80 | 81 | private ContentAwareFillConfigToken(ContentAwareFillConfigToken cloneMe) 82 | { 83 | this.SampleSize = cloneMe.SampleSize; 84 | this.SampleFrom = cloneMe.SampleFrom; 85 | this.FillDirection = cloneMe.FillDirection; 86 | this.Seed = cloneMe.Seed; 87 | this.RenderAutomatically = cloneMe.RenderAutomatically; 88 | this.Output = cloneMe.Output; 89 | } 90 | 91 | public override object Clone() 92 | { 93 | return new ContentAwareFillConfigToken(this); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Resynthesizer/PointIndexedArray.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using ContentAwareFill.Collections; 24 | using PaintDotNet; 25 | using PaintDotNet.Rendering; 26 | using System; 27 | using System.Threading; 28 | 29 | namespace ContentAwareFill 30 | { 31 | internal sealed unsafe class PointIndexedArray : Disposable where T : unmanaged 32 | { 33 | private readonly NativeArray items; 34 | private readonly uint stride; 35 | 36 | public PointIndexedArray(SizeInt32 size, T defaultValue, CancellationToken cancellationToken) 37 | { 38 | this.stride = checked((uint)size.Width); 39 | uint height = checked((uint)size.Height); 40 | 41 | this.items = new((nuint)this.stride * height); 42 | 43 | for (uint y = 0; y < height; y++) 44 | { 45 | cancellationToken.ThrowIfCancellationRequested(); 46 | 47 | new Span(this.items.GetAddress((nuint)y * this.stride), size.Width).Fill(defaultValue); 48 | } 49 | } 50 | 51 | public T this[Point2Int32 target] 52 | { 53 | get 54 | { 55 | return GetValue(target.X, target.Y); 56 | } 57 | set 58 | { 59 | SetValue(target.X, target.Y, value); 60 | } 61 | } 62 | 63 | public T GetValue(int x, int y) 64 | { 65 | ArgumentOutOfRangeException.ThrowIfNegative(x, nameof(x)); 66 | ArgumentOutOfRangeException.ThrowIfNegative(y, nameof(y)); 67 | 68 | nuint index = ((nuint)((uint)y) * this.stride) + (uint)x; 69 | 70 | return this.items[index]; 71 | } 72 | 73 | public void SetValue(int x, int y, T value) 74 | { 75 | ArgumentOutOfRangeException.ThrowIfNegative(x, nameof(x)); 76 | ArgumentOutOfRangeException.ThrowIfNegative(y, nameof(y)); 77 | 78 | nuint index = ((nuint)((uint)y) * this.stride) + (uint)x; 79 | 80 | this.items[index] = value; 81 | } 82 | 83 | protected override void Dispose(bool disposing) 84 | { 85 | if (disposing) 86 | { 87 | this.items.Dispose(); 88 | } 89 | 90 | base.Dispose(disposing); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Collections/NativeArray_1.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet; 24 | using System; 25 | using System.Diagnostics.CodeAnalysis; 26 | using System.Runtime.InteropServices; 27 | 28 | namespace ContentAwareFill.Collections 29 | { 30 | internal unsafe sealed class NativeArray : Disposable where T : unmanaged 31 | { 32 | private T* pointer; 33 | private readonly nuint elementCount; 34 | 35 | public NativeArray(nuint elementCount) 36 | { 37 | nuint sizeInBytes = elementCount * (uint)sizeof(T); 38 | 39 | this.pointer = (T*)NativeMemory.Alloc(sizeInBytes); 40 | this.elementCount = elementCount; 41 | 42 | if (sizeInBytes > 0 && sizeInBytes <= long.MaxValue) 43 | { 44 | GC.AddMemoryPressure((long)sizeInBytes); 45 | } 46 | } 47 | 48 | public T this[nuint index] 49 | { 50 | get 51 | { 52 | return *GetAddress(index); 53 | } 54 | set 55 | { 56 | T* ptr = GetAddress(index); 57 | *ptr = value; 58 | } 59 | } 60 | 61 | public T* GetAddress(nuint index) 62 | { 63 | if (index >= this.elementCount) 64 | { 65 | ThrowArgumentOutOfRangeException(index); 66 | } 67 | ObjectDisposedException.ThrowIf(this.pointer is null, null); 68 | 69 | return this.pointer + index; 70 | } 71 | 72 | protected override void Dispose(bool disposing) 73 | { 74 | T* ptr = this.pointer; 75 | this.pointer = null; 76 | 77 | if (ptr != null) 78 | { 79 | NativeMemory.Free(ptr); 80 | 81 | nuint sizeInBytes = this.elementCount * (uint)sizeof(T); 82 | 83 | if (sizeInBytes > 0 && sizeInBytes <= long.MaxValue) 84 | { 85 | GC.RemoveMemoryPressure((long)sizeInBytes); 86 | } 87 | } 88 | base.Dispose(disposing); 89 | } 90 | 91 | [DoesNotReturn] 92 | private void ThrowArgumentOutOfRangeException(nuint index) 93 | { 94 | throw new ArgumentOutOfRangeException( 95 | nameof(index), 96 | $"{nameof(index)} must be less than {this.elementCount}, actual value: {index}."); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/BitmapUtil.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet; 24 | using PaintDotNet.Effects; 25 | using PaintDotNet.Imaging; 26 | using PaintDotNet.Rendering; 27 | using System; 28 | 29 | namespace ContentAwareFill 30 | { 31 | internal static class BitmapUtil 32 | { 33 | internal static unsafe IBitmap CreateFromBitmap(IImagingFactory imagingFactory, 34 | IEffectInputBitmap source, 35 | SizeInt32 size, 36 | RectInt32 sourceRoi) where TPixel : unmanaged, INaturalPixelInfo 37 | 38 | { 39 | IBitmap destination = imagingFactory.CreateBitmap(size); 40 | 41 | using (IBitmapLock sourceLock = source.Lock(GetSourceRect(size, sourceRoi))) 42 | using (IBitmapLock destinationLock = destination.Lock(BitmapLockOptions.Write)) 43 | { 44 | sourceLock.AsRegionPtr().CopyTo(destinationLock.AsRegionPtr()); 45 | } 46 | 47 | return destination; 48 | } 49 | 50 | internal static unsafe IBitmap CreateFromBitmap(IImagingFactory imagingFactory, 51 | IBitmap source, 52 | SizeInt32 size, 53 | RectInt32 sourceRoi, 54 | bool clear = false) where TPixel : unmanaged, INaturalPixelInfo 55 | 56 | { 57 | IBitmap destination = imagingFactory.CreateBitmap(size); 58 | 59 | using (IBitmapLock sourceLock = source.Lock(GetSourceRect(size, sourceRoi), BitmapLockOptions.Read)) 60 | using (IBitmapLock destinationLock = destination.Lock(BitmapLockOptions.Write)) 61 | { 62 | RegionPtr sourceRegion = sourceLock.AsRegionPtr(); 63 | RegionPtr destRegion = destinationLock.AsRegionPtr(); 64 | 65 | if (clear) 66 | { 67 | destRegion.Clear(); 68 | } 69 | 70 | sourceRegion.CopyTo(destRegion); 71 | } 72 | 73 | return destination; 74 | } 75 | 76 | private static RectInt32 GetSourceRect(SizeInt32 destinationSize, RectInt32 sourceRoi) 77 | { 78 | int copyWidth = Math.Min(destinationSize.Width, sourceRoi.Width); 79 | int copyHeight = Math.Min(destinationSize.Height, sourceRoi.Height); 80 | 81 | return new(sourceRoi.Location, copyWidth, copyHeight); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Resynthesizer/PointIndexedBitArray.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet.Rendering; 24 | using System; 25 | using System.Diagnostics.CodeAnalysis; 26 | using System.Runtime.CompilerServices; 27 | 28 | namespace ContentAwareFill 29 | { 30 | internal readonly struct PointIndexedBitArray 31 | { 32 | private readonly ulong[] blocks; 33 | private readonly int width; 34 | private readonly int height; 35 | 36 | private PointIndexedBitArray(SizeInt32 size) 37 | { 38 | this.width = size.Width; 39 | this.height = size.Height; 40 | 41 | int area = checked(this.width * this.height); 42 | 43 | int blockCount = area > 64 ? ((area - 1) / 64) + 1 : 1; 44 | this.blocks = new ulong[blockCount]; 45 | } 46 | 47 | public static PointIndexedBitArray CreateFalse(SizeInt32 size) 48 | { 49 | return new PointIndexedBitArray(size); 50 | } 51 | 52 | public bool this[Point2Int32 target] 53 | { 54 | get => GetValue(target.X, target.Y); 55 | set => SetValue(target.X, target.Y, value); 56 | } 57 | 58 | public bool GetValue(int x, int y) 59 | { 60 | CheckBounds(x, y); 61 | 62 | int index = (y * this.width) + x; 63 | 64 | (int blockIndex, int bitIndex) = Div64Rem(index); 65 | 66 | return (this.blocks[blockIndex] & (1UL << bitIndex)) != 0; 67 | } 68 | 69 | public void SetValue(int x, int y, bool value) 70 | { 71 | CheckBounds(x, y); 72 | 73 | int index = (y * this.width) + x; 74 | 75 | (int blockIndex, int bitIndex) = Div64Rem(index); 76 | 77 | ref ulong segment = ref this.blocks[blockIndex]; 78 | ulong bit = 1UL << bitIndex; 79 | 80 | if (value) 81 | { 82 | segment |= bit; 83 | } 84 | else 85 | { 86 | segment &= ~bit; 87 | } 88 | } 89 | 90 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 91 | private static (int Quotent, int Remainder) Div64Rem(int number) 92 | { 93 | // The uint cast is required for the JIT to optimize the division by 64 94 | // into a shift right by 6 in assembly. 95 | // A lot of bit shifting tricks are only valid for unsigned values. 96 | uint quotent = (uint)number / 64; 97 | int remainder = number & 63; // Equivalent to number % 64, since 64 is a power of 2. 98 | 99 | return ((int)quotent, remainder); 100 | } 101 | 102 | [DoesNotReturn] 103 | private static void ThrowIndexOutOfRangeException() 104 | { 105 | throw new IndexOutOfRangeException(); 106 | } 107 | 108 | private void CheckBounds(int x, int y) 109 | { 110 | if ((uint)x >= (uint)this.width) 111 | { 112 | ThrowIndexOutOfRangeException(); 113 | } 114 | 115 | if ((uint)y >= (uint)this.height) 116 | { 117 | ThrowIndexOutOfRangeException(); 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/PaintDotNet/EtchedLine.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////////// 2 | // Paint.NET // 3 | // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. // 4 | // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. // 5 | // See License-pdn.txt for full licensing and attribution // 6 | // details. // 7 | // . // 8 | ///////////////////////////////////////////////////////////////////////////////// 9 | 10 | using System.ComponentModel; 11 | using System.Drawing; 12 | using System.Windows.Forms; 13 | using System.Windows.Forms.VisualStyles; 14 | 15 | namespace ContentAwareFill 16 | { 17 | internal sealed class EtchedLine 18 | : Control 19 | { 20 | private bool selfDrawn = false; 21 | private Label label; 22 | 23 | public void InitForCurrentVisualStyle() 24 | { 25 | // If we are Vista Aero, draw using a GroupBox 26 | // Else, use the "etched line via a label w/ a border style" trick 27 | // We would use the "GroupBox" style w/ Luna, except that it wasn't 28 | // working correctly for some reason. 29 | 30 | switch (UI.VisualStyleClass) 31 | { 32 | case VisualStyleClass.Aero: 33 | this.selfDrawn = true; 34 | break; 35 | 36 | case VisualStyleClass.Luna: 37 | case VisualStyleClass.Classic: 38 | case VisualStyleClass.Other: 39 | this.selfDrawn = false; 40 | break; 41 | 42 | default: 43 | throw new InvalidEnumArgumentException(); 44 | } 45 | 46 | if (this.selfDrawn && (this.label != null && this.Controls.Contains(this.label))) 47 | { 48 | SuspendLayout(); 49 | this.Controls.Remove(this.label); 50 | ResumeLayout(false); 51 | PerformLayout(); 52 | Invalidate(true); 53 | } 54 | else if (!this.selfDrawn && (this.label != null || !this.Controls.Contains(this.label))) 55 | { 56 | if (this.label == null) 57 | { 58 | this.label = new Label(); 59 | this.label.BorderStyle = BorderStyle.Fixed3D; 60 | } 61 | 62 | SuspendLayout(); 63 | this.Controls.Add(this.label); 64 | ResumeLayout(false); 65 | PerformLayout(); 66 | Invalidate(true); 67 | } 68 | } 69 | 70 | public EtchedLine() 71 | { 72 | InitForCurrentVisualStyle(); 73 | this.DoubleBuffered = true; 74 | this.ResizeRedraw = true; 75 | this.TabStop = false; 76 | SetStyle(ControlStyles.Selectable, false); 77 | } 78 | 79 | public override Size GetPreferredSize(Size proposedSize) 80 | { 81 | return new Size(proposedSize.Width, 2); 82 | } 83 | 84 | protected override void Dispose(bool disposing) 85 | { 86 | if (disposing) 87 | { 88 | this.label?.Dispose(); 89 | } 90 | 91 | base.Dispose(disposing); 92 | } 93 | 94 | protected override void OnPaint(PaintEventArgs e) 95 | { 96 | if (this.selfDrawn) 97 | { 98 | GroupBoxRenderer.DrawGroupBox(e.Graphics, new Rectangle(0, 0, this.Width, 1), GroupBoxState.Normal); 99 | } 100 | 101 | base.OnPaint(e); 102 | } 103 | 104 | protected override void OnLayout(LayoutEventArgs levent) 105 | { 106 | if (!this.selfDrawn) 107 | { 108 | this.label.Bounds = new Rectangle(0, 0, this.Width, this.Height); 109 | } 110 | 111 | base.OnLayout(levent); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/ContentAwareFill.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0-windows7.0 4 | Library 5 | false 6 | true 7 | true 8 | true 9 | MinimumRecommendedRules.ruleset 10 | 11 | 12 | true 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | True 36 | 37 | 38 | 39 | 40 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Base.dll 41 | 42 | 43 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.ComponentModel.dll 44 | 45 | 46 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Core.dll 47 | 48 | 49 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Effects.Core.dll 50 | 51 | 52 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Framework.dll 53 | 54 | 55 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Fundamentals.dll 56 | 57 | 58 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.ObjectModel.dll 59 | 60 | 61 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Primitives.dll 62 | 63 | 64 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Windows.dll 65 | 66 | 67 | ..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Windows.Core.dll 68 | 69 | 70 | 71 | 72 | True 73 | True 74 | Resources.resx 75 | 76 | 77 | ResXFileCodeGenerator 78 | Resources.Designer.cs 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/PaintDotNet/UI.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////////// 2 | // Paint.NET // 3 | // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. // 4 | // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. // 5 | // See License-pdn.txt for full licensing and attribution // 6 | // details. // 7 | // . // 8 | ///////////////////////////////////////////////////////////////////////////////// 9 | 10 | 11 | using System; 12 | using System.Drawing; 13 | using System.Windows.Forms; 14 | using System.Windows.Forms.VisualStyles; 15 | 16 | namespace ContentAwareFill 17 | { 18 | 19 | 20 | /// 21 | /// Contains static methods related to the user interface. 22 | /// 23 | internal static class UI 24 | { 25 | private static bool initScales = false; 26 | private static float xScale; 27 | 28 | private static void InitScaleFactors(Control c) 29 | { 30 | if (c == null) 31 | { 32 | xScale = 1.0f; 33 | } 34 | else 35 | { 36 | using (Graphics g = c.CreateGraphics()) 37 | { 38 | xScale = g.DpiX / 96.0f; 39 | } 40 | } 41 | 42 | initScales = true; 43 | } 44 | 45 | public static void InitScaling(Control c) 46 | { 47 | if (!initScales) 48 | { 49 | InitScaleFactors(c); 50 | } 51 | } 52 | 53 | private static VisualStyleClass DetermineVisualStyleClassImpl() 54 | { 55 | VisualStyleClass vsClass; 56 | 57 | try 58 | { 59 | if (!VisualStyleInformation.IsSupportedByOS) 60 | { 61 | vsClass = VisualStyleClass.Classic; 62 | } 63 | else if (!VisualStyleInformation.IsEnabledByUser) 64 | { 65 | vsClass = VisualStyleClass.Classic; 66 | } 67 | else if (0 == string.Compare(VisualStyleInformation.Author, "MSX", StringComparison.InvariantCulture) && 68 | 0 == string.Compare(VisualStyleInformation.DisplayName, "Aero style", StringComparison.InvariantCulture)) 69 | { 70 | vsClass = VisualStyleClass.Aero; 71 | } 72 | else if (0 == string.Compare(VisualStyleInformation.Company, "Microsoft Corporation", StringComparison.InvariantCulture) && 73 | 0 == string.Compare(VisualStyleInformation.Author, "Microsoft Design Team", StringComparison.InvariantCulture)) 74 | { 75 | if (0 == string.Compare(VisualStyleInformation.DisplayName, "Windows XP style", StringComparison.InvariantCulture) || // Luna 76 | 0 == string.Compare(VisualStyleInformation.DisplayName, "Zune Style", StringComparison.InvariantCulture) || // Zune 77 | 0 == string.Compare(VisualStyleInformation.DisplayName, "Media Center style", StringComparison.InvariantCulture)) // Royale 78 | { 79 | vsClass = VisualStyleClass.Luna; 80 | } 81 | else 82 | { 83 | vsClass = VisualStyleClass.Other; 84 | } 85 | } 86 | else 87 | { 88 | vsClass = VisualStyleClass.Other; 89 | } 90 | } 91 | catch (Exception) 92 | { 93 | vsClass = VisualStyleClass.Other; 94 | } 95 | 96 | return vsClass; 97 | } 98 | 99 | public static VisualStyleClass VisualStyleClass 100 | { 101 | get 102 | { 103 | return DetermineVisualStyleClassImpl(); 104 | } 105 | } 106 | 107 | public static float GetXScaleFactor() 108 | { 109 | if (!initScales) 110 | { 111 | throw new InvalidOperationException("Must call InitScaling() first"); 112 | } 113 | 114 | return xScale; 115 | } 116 | 117 | public static int ScaleWidth(int width) 118 | { 119 | return (int)Math.Round((float)width * GetXScaleFactor()); 120 | } 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Resynthesizer/Comparers/DirectionalPointComparer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * The Resynthesizer - A GIMP plug-in for resynthesizing textures 26 | * 27 | * Copyright (C) 2010 Lloyd Konneker 28 | * Copyright (C) 2000 2008 Paul Francis Harrison 29 | * Copyright (C) 2002 Laurent Despeyroux 30 | * Copyright (C) 2002 David Rodríguez García 31 | * 32 | * This program is free software; you can redistribute it and/or modify 33 | * it under the terms of the GNU General Public License as published by 34 | * the Free Software Foundation; either version 2 of the License, or 35 | * (at your option) any later version. 36 | * 37 | * This program is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 | * GNU General Public License for more details. 41 | * 42 | * You should have received a copy of the GNU General Public License 43 | * along with this program; if not, write to the Free Software 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 | * 46 | */ 47 | 48 | using PaintDotNet.Rendering; 49 | using System; 50 | using System.Buffers; 51 | using System.Collections.Generic; 52 | using System.Threading; 53 | 54 | namespace ContentAwareFill 55 | { 56 | internal struct DirectionalPointComparer : IComparer, IDisposable 57 | { 58 | private readonly uint[] maxCartesianAlongRay; 59 | private readonly bool outward; 60 | private int disposed; 61 | 62 | public DirectionalPointComparer(IEnumerable targetPoints, bool outward) 63 | { 64 | ArgumentNullException.ThrowIfNull(targetPoints); 65 | 66 | this.maxCartesianAlongRay = ArrayPool.Shared.Rent(401); 67 | 68 | Point2Int32 center = PointCollectionUtil.GetCenter(targetPoints); 69 | 70 | foreach (Point2Int32 point in targetPoints) 71 | { 72 | Point2Int32 offset = point.Subtract(center); 73 | 74 | uint cartesian = (uint)((offset.X * offset.X) + (offset.Y * offset.Y)); 75 | 76 | uint ray = GetRadial(offset); 77 | if (cartesian > this.maxCartesianAlongRay[ray]) 78 | { 79 | this.maxCartesianAlongRay[ray] = cartesian; 80 | } 81 | } 82 | this.outward = outward; 83 | } 84 | 85 | public int Compare(Point2Int32 point1, Point2Int32 point2) 86 | { 87 | ObjectDisposedException.ThrowIf(Volatile.Read(ref this.disposed) == 1, null); 88 | 89 | float point1Proportion = ProportionInward(point1); 90 | float point2Proportion = ProportionInward(point2); 91 | 92 | if (this.outward) 93 | { 94 | return point2Proportion.CompareTo(point1Proportion); 95 | } 96 | else 97 | { 98 | return point1Proportion.CompareTo(point2Proportion); 99 | } 100 | } 101 | 102 | public void Dispose() 103 | { 104 | if (Interlocked.Exchange(ref this.disposed, 1) == 0) 105 | { 106 | ArrayPool.Shared.Return(this.maxCartesianAlongRay); 107 | } 108 | } 109 | 110 | private readonly float ProportionInward(Point2Int32 point) 111 | { 112 | uint ray = GetRadial(point); 113 | 114 | return (float)((point.X * point.X) + (point.Y * point.Y)) / this.maxCartesianAlongRay[ray]; 115 | } 116 | 117 | private static uint GetRadial(Point2Int32 point) 118 | { 119 | return (uint)((Math.Atan2(point.Y, point.X) * 200 / Math.PI) + 200); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/PluginThemingUtil.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using System; 24 | using System.Collections.Generic; 25 | using System.Drawing; 26 | using System.Windows.Forms; 27 | 28 | namespace ContentAwareFill 29 | { 30 | internal static class PluginThemingUtil 31 | { 32 | /// 33 | /// Updates the background color of the controls. 34 | /// 35 | /// The root control. 36 | /// is null. 37 | public static void UpdateControlBackColor(Control root) 38 | { 39 | ArgumentNullException.ThrowIfNull(root); 40 | 41 | Color backColor = root.BackColor; 42 | 43 | Stack stack = new(); 44 | stack.Push(root); 45 | 46 | while (stack.Count > 0) 47 | { 48 | Control parent = stack.Pop(); 49 | 50 | Control.ControlCollection controls = parent.Controls; 51 | 52 | for (int i = 0; i < controls.Count; i++) 53 | { 54 | Control control = controls[i]; 55 | 56 | if (control is Button button) 57 | { 58 | // Reset the BackColor of all Button controls. 59 | button.UseVisualStyleBackColor = true; 60 | } 61 | else 62 | { 63 | // Update the BackColor for all child controls as some controls 64 | // do not change the BackColor when the parent control does. 65 | 66 | control.BackColor = backColor; 67 | 68 | if (control.HasChildren) 69 | { 70 | stack.Push(control); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | 77 | /// 78 | /// Updates the foreground color of the controls. 79 | /// 80 | /// The root control. 81 | /// is null. 82 | public static void UpdateControlForeColor(Control root) 83 | { 84 | ArgumentNullException.ThrowIfNull(root); 85 | 86 | Color foreColor = root.ForeColor; 87 | 88 | Stack stack = new(); 89 | stack.Push(root); 90 | 91 | while (stack.Count > 0) 92 | { 93 | Control parent = stack.Pop(); 94 | 95 | Control.ControlCollection controls = parent.Controls; 96 | 97 | for (int i = 0; i < controls.Count; i++) 98 | { 99 | Control control = controls[i]; 100 | 101 | if (control is Button button) 102 | { 103 | // Reset the ForeColor of all Button controls. 104 | button.ForeColor = SystemColors.ControlText; 105 | } 106 | else if (control is LinkLabel link) 107 | { 108 | if (foreColor != Control.DefaultForeColor) 109 | { 110 | link.LinkColor = foreColor; 111 | } 112 | else 113 | { 114 | // If the control is using the default foreground color set the link color 115 | // to Color.Empty so the LinkLabel will use its default colors. 116 | link.LinkColor = Color.Empty; 117 | } 118 | } 119 | else 120 | { 121 | // Update the ForeColor for all child controls as some controls 122 | // do not change the ForeColor when the parent control does. 123 | 124 | control.ForeColor = foreColor; 125 | 126 | if (control.HasChildren) 127 | { 128 | stack.Push(control); 129 | } 130 | } 131 | } 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/PaintDotNet/HeaderLabel.cs: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////////// 2 | // Paint.NET // 3 | // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. // 4 | // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. // 5 | // See License-pdn.txt for full licensing and attribution // 6 | // details. // 7 | // . // 8 | ///////////////////////////////////////////////////////////////////////////////// 9 | 10 | using System; 11 | using System.ComponentModel; 12 | using System.Drawing; 13 | using System.Windows.Forms; 14 | 15 | namespace ContentAwareFill 16 | { 17 | internal sealed class HeaderLabel 18 | : Control 19 | { 20 | private const TextFormatFlags textFormatFlags = 21 | TextFormatFlags.Default | 22 | TextFormatFlags.EndEllipsis | 23 | TextFormatFlags.HidePrefix | 24 | TextFormatFlags.NoPadding | 25 | TextFormatFlags.NoPrefix | 26 | TextFormatFlags.SingleLine; 27 | 28 | private readonly int leftMargin = 2; 29 | private int rightMargin = 8; 30 | 31 | private readonly EtchedLine etchedLine; 32 | 33 | [DefaultValue(8)] 34 | public int RightMargin 35 | { 36 | get 37 | { 38 | return this.rightMargin; 39 | } 40 | 41 | set 42 | { 43 | this.rightMargin = value; 44 | PerformLayout(); 45 | } 46 | } 47 | 48 | protected override void Dispose(bool disposing) 49 | { 50 | if (disposing) 51 | { 52 | this.etchedLine?.Dispose(); 53 | } 54 | 55 | base.Dispose(disposing); 56 | } 57 | 58 | protected override void OnFontChanged(EventArgs e) 59 | { 60 | PerformLayout(); 61 | Refresh(); 62 | base.OnFontChanged(e); 63 | } 64 | 65 | protected override void OnTextChanged(EventArgs e) 66 | { 67 | PerformLayout(); 68 | Refresh(); 69 | base.OnTextChanged(e); 70 | } 71 | 72 | public HeaderLabel() 73 | { 74 | SetStyle(ControlStyles.AllPaintingInWmPaint, true); 75 | SetStyle(ControlStyles.Opaque, true); 76 | SetStyle(ControlStyles.ResizeRedraw, true); 77 | SetStyle(ControlStyles.UserPaint, true); 78 | SetStyle(ControlStyles.Selectable, false); 79 | UI.InitScaling(null); 80 | this.TabStop = false; 81 | this.ForeColor = SystemColors.Highlight; 82 | this.DoubleBuffered = true; 83 | this.ResizeRedraw = true; 84 | 85 | SuspendLayout(); 86 | this.etchedLine = new EtchedLine(); 87 | this.Controls.Add(this.etchedLine); 88 | this.Size = new Size(144, 14); 89 | ResumeLayout(false); 90 | } 91 | 92 | private int GetPreferredWidth(Size proposedSize) 93 | { 94 | Size textSize = GetTextSize(); 95 | return this.leftMargin + textSize.Width; 96 | } 97 | 98 | public override Size GetPreferredSize(Size proposedSize) 99 | { 100 | return new Size(Math.Max(proposedSize.Width, GetPreferredWidth(proposedSize)), GetTextSize().Height); 101 | } 102 | 103 | private Size GetTextSize() 104 | { 105 | string textToUse = string.IsNullOrEmpty(this.Text) ? " " : this.Text; 106 | 107 | Size size = TextRenderer.MeasureText(textToUse, this.Font, this.ClientSize, textFormatFlags); 108 | 109 | if (string.IsNullOrEmpty(this.Text)) 110 | { 111 | size.Width = 0; 112 | } 113 | 114 | return size; 115 | } 116 | 117 | protected override void OnLayout(LayoutEventArgs levent) 118 | { 119 | Size textSize = GetTextSize(); 120 | 121 | int lineLeft = (string.IsNullOrEmpty(this.Text) ? 0 : this.leftMargin) + textSize.Width + (string.IsNullOrEmpty(this.Text) ? 0 : 1); 122 | int lineRight = this.ClientRectangle.Right - this.rightMargin; 123 | 124 | this.etchedLine.Size = this.etchedLine.GetPreferredSize(new Size(lineRight - lineLeft, 1)); 125 | this.etchedLine.Location = new Point(lineLeft, (this.ClientSize.Height - this.etchedLine.Height) / 2); 126 | 127 | base.OnLayout(levent); 128 | } 129 | 130 | protected override void OnPaint(PaintEventArgs e) 131 | { 132 | using (SolidBrush backBrush = new(this.BackColor)) 133 | { 134 | e.Graphics.FillRectangle(backBrush, e.ClipRectangle); 135 | } 136 | 137 | Size textSize = GetTextSize(); 138 | Color textColor = this.BackColor != DefaultBackColor ? this.ForeColor : SystemColors.WindowText; 139 | TextRenderer.DrawText(e.Graphics, this.Text, this.Font, new Point(this.leftMargin, 0), textColor, textFormatFlags); 140 | 141 | base.OnPaint(e); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ContentAwareFill.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ContentAwareFill.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap ResetIcon_96 { 67 | get { 68 | object obj = ResourceManager.GetObject("ResetIcon_96", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized string similar to The source region is empty. Does the area outside the selection include any non-transparent pixels?. 75 | /// 76 | internal static string SourcePointsEmpty { 77 | get { 78 | return ResourceManager.GetString("SourcePointsEmpty", resourceCulture); 79 | } 80 | } 81 | 82 | /// 83 | /// Looks up a localized string similar to Initializing.... 84 | /// 85 | internal static string StatusInitializingText { 86 | get { 87 | return ResourceManager.GetString("StatusInitializingText", resourceCulture); 88 | } 89 | } 90 | 91 | /// 92 | /// Looks up a localized string similar to Ready. 93 | /// 94 | internal static string StatusReadyText { 95 | get { 96 | return ResourceManager.GetString("StatusReadyText", resourceCulture); 97 | } 98 | } 99 | 100 | /// 101 | /// Looks up a localized string similar to Rendering.... 102 | /// 103 | internal static string StatusRenderingText { 104 | get { 105 | return ResourceManager.GetString("StatusRenderingText", resourceCulture); 106 | } 107 | } 108 | 109 | /// 110 | /// Looks up a localized string similar to The target layer is empty. Does the selection include any non-transparent pixels?. 111 | /// 112 | internal static string TargetPointsEmpty { 113 | get { 114 | return ResourceManager.GetString("TargetPointsEmpty", resourceCulture); 115 | } 116 | } 117 | 118 | /// 119 | /// Looks up a localized string similar to There is no active selection or the entire image is selected. 120 | /// 121 | ///This plugin requires that a portion of the image remain unselected so that it can replace the contents of the selection with pixels that are the closest match in the unselected area.. 122 | /// 123 | internal static string WholeImageSelected { 124 | get { 125 | return ResourceManager.GetString("WholeImageSelected", resourceCulture); 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Third Party Notices.txt: -------------------------------------------------------------------------------- 1 | This file lists the original copyright and license information for 2 | the third-party libraries or other resources included with this software. 3 | 4 | The attached notices are provided for information only. 5 | 6 | License notice for Resynthesizer 7 | -------------------------------------------------------------- 8 | 9 | Copyright (C) 2010 Lloyd Konneker 10 | Copyright (C) 2000 2008 Paul Francis Harrison 11 | Copyright (C) 2002 Laurent Despeyroux 12 | Copyright (C) 2002 David Rodríguez García 13 | 14 | This program is free software; you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation; either version 2 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | 24 | You should have received a copy of the GNU General Public License 25 | along with this program; if not, write to the Free Software 26 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 | 28 | License notice for Paint.NET 3.36 29 | -------------------------------------------------------------- 30 | 31 | Paint.NET 32 | Copyright (C) dotPDN LLC, Rick Brewster, Chris Crosetto, Tom Jackson, Michael Kelsey, Brandon Ortiz, Craig Taylor, Chris Trevino, and Luke Walker. 33 | Portions Copyright (C) Microsoft Corporation. All Rights Reserved. 34 | 35 | License last updated: June 1, 2008 36 | 37 | For more licensing information and answers to Frequently Asked Questions, please go to: http://www.getpaint.net/license.html 38 | 39 | This software is licensed as per the MIT License below, but with three (3) exceptions: 40 | 41 | * Exception 1: The Paint.NET logo and icon artwork are Copyright (C) Rick Brewster. They are covered by the Creative Commons Attribution-NonCommercial-NoDerivs 2.5 license which is detailed here: http://creativecommons.org/licenses/by-nc-nd/2.5/ . However, permission is granted to use the logo and icon artwork in ways that directly discuss or promote Paint.NET (e.g. blog and news posts about Paint.NET, "Made with Paint.NET" watermarks or insets). 42 | 43 | * Exception 2: Paint.NET makes use of certain text and graphic resources that it comes with (e.g., toolbar icon graphics, text for menu items and the status bar). These are collectively referred to as "resource assets" and are defined to include the contents of files installed by Paint.NET, or included in its source code distribution, that have a .RESOURCES, .RESX, or .PNG file extension. This also includes embedded resource files within the PaintDotNet.Resources.dll installed file. These "resource assets" are covered by the Creative Commons Attribution-NonCommercial-NoDerivs 2.5 license which is detailed here: http://creativecommons.org/licenses/by-nc-nd/2.5/ . However, permission is granted to create and distribute derivative works of the "resource assets" for the sole purpose of providing a translation to a language other than English. Some "resource assets" are included in unmodified form from external icon or image libraries and are still covered by their original, respective licenses (e.g., "Silk", "Visual Studio 2005 Image Library"). 44 | 45 | * Exception 3: Although the Paint.NET source code distribution includes the GPC source code, use of the GPC code in any other commercial application is not permitted without a GPC Commercial Use Licence from The University of Manchester. For more information, please refer to the GPC website at: http://www.cs.man.ac.uk/~toby/alan/software/ 46 | 47 | MIT License: http://www.opensource.org/licenses/mit-license.php 48 | 49 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 50 | 51 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 52 | 53 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 54 | 55 | 56 | License notice for Collections.Pooled 57 | -------------------------------------------------------------- 58 | 59 | The MIT License (MIT) 60 | 61 | Copyright (c) Joel Mueller 62 | 63 | All rights reserved. 64 | 65 | Permission is hereby granted, free of charge, to any person obtaining a copy 66 | of this software and associated documentation files (the "Software"), to deal 67 | in the Software without restriction, including without limitation the rights 68 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 69 | copies of the Software, and to permit persons to whom the Software is 70 | furnished to do so, subject to the following conditions: 71 | 72 | The above copyright notice and this permission notice shall be included in all 73 | copies or substantial portions of the Software. 74 | 75 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 76 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 77 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 78 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 79 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 80 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 81 | SOFTWARE. -------------------------------------------------------------------------------- /src/ContentAwareFillConfigDialog.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 174, 17 125 | 126 | -------------------------------------------------------------------------------- /src/Resynthesizer/TargetPointSorter.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * 25 | * The Resynthesizer - A GIMP plug-in for resynthesizing textures 26 | * 27 | * Copyright (C) 2010 Lloyd Konneker 28 | * Copyright (C) 2000 2008 Paul Francis Harrison 29 | * Copyright (C) 2002 Laurent Despeyroux 30 | * Copyright (C) 2002 David Rodríguez García 31 | * 32 | * This program is free software; you can redistribute it and/or modify 33 | * it under the terms of the GNU General Public License as published by 34 | * the Free Software Foundation; either version 2 of the License, or 35 | * (at your option) any later version. 36 | * 37 | * This program is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 | * GNU General Public License for more details. 41 | * 42 | * You should have received a copy of the GNU General Public License 43 | * along with this program; if not, write to the Free Software 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 | * 46 | */ 47 | 48 | using Collections.Pooled; 49 | using PaintDotNet.Rendering; 50 | using System; 51 | using System.Collections.Generic; 52 | using System.ComponentModel; 53 | 54 | namespace ContentAwareFill 55 | { 56 | internal static class TargetPointSorter 57 | { 58 | internal static void Sort(PooledList points, int randomSeed, MatchContextType matchContextType) 59 | { 60 | switch (matchContextType) 61 | { 62 | case MatchContextType.None: 63 | case MatchContextType.Random: 64 | OrderTargetPointsRandom(points, randomSeed); 65 | break; 66 | case MatchContextType.InwardConcentric: 67 | using (DirectionalPointComparer comparer = new(points, outward: false)) 68 | { 69 | OrderTargetPointsRandomDirectional(points, randomSeed, comparer); 70 | } 71 | break; 72 | case MatchContextType.InwardHorizontal: 73 | OrderTargetPointsRandomDirectional(points, randomSeed, new HorizontalPointComparer(outward: false)); 74 | break; 75 | case MatchContextType.InwardVertical: 76 | OrderTargetPointsRandomDirectional(points, randomSeed, new VerticalPointComparer(outward: false)); 77 | break; 78 | case MatchContextType.OutwardConcentric: 79 | using (DirectionalPointComparer comparer = new(points, outward: true)) 80 | { 81 | OrderTargetPointsRandomDirectional(points, randomSeed, comparer); 82 | } 83 | break; 84 | case MatchContextType.OutwardHorizontal: 85 | OrderTargetPointsRandomDirectional(points, randomSeed, new HorizontalPointComparer(outward: true)); 86 | break; 87 | case MatchContextType.OutwardVertical: 88 | OrderTargetPointsRandomDirectional(points, randomSeed, new VerticalPointComparer(outward: true)); 89 | break; 90 | default: 91 | throw new InvalidEnumArgumentException(nameof(matchContextType), (int)matchContextType, typeof(MatchContextType)); 92 | } 93 | } 94 | 95 | private static void OrderTargetPointsRandom(PooledList points, int randomSeed) 96 | { 97 | int count = points.Count; 98 | ResynthesizerRandom random = new(randomSeed); 99 | 100 | for (int i = 0; i < count; i++) 101 | { 102 | int j = random.Next(count); 103 | 104 | (points[j], points[i]) = (points[i], points[j]); 105 | } 106 | } 107 | 108 | private static void TargetPointsToOffsets(PooledList points, Point2Int32 center) 109 | { 110 | for (int i = 0; i < points.Count; i++) 111 | { 112 | points[i] = points[i].Subtract(center); 113 | } 114 | } 115 | 116 | private static void TargetPointsFromOffsets(PooledList points, Point2Int32 center) 117 | { 118 | for (int i = 0; i < points.Count; i++) 119 | { 120 | points[i] = points[i].Add(center); 121 | } 122 | } 123 | 124 | private static void RandomizeBandsTargetPoints(PooledList points, int randomSeed) 125 | { 126 | int last = points.Count - 1; 127 | int halfBand = (int)(points.Count * ResynthesizerConstants.BandFraction); 128 | ResynthesizerRandom random = new(randomSeed); 129 | 130 | for (int i = 0; i <= last; i++) 131 | { 132 | int bandStart = Math.Max(i - halfBand, 0); 133 | int bandEnd = Math.Min(i + halfBand, last); 134 | int bandSize = bandEnd - bandStart; 135 | 136 | int j = bandStart + random.Next(bandSize); 137 | 138 | (points[j], points[i]) = (points[i], points[j]); 139 | } 140 | } 141 | 142 | private static void OrderTargetPointsRandomDirectional(PooledList points, 143 | int randomSeed, 144 | TComparer pointComparer) where TComparer : struct, IComparer 145 | { 146 | Point2Int32 center = PointCollectionUtil.GetCenter(points); 147 | 148 | TargetPointsToOffsets(points, center); 149 | 150 | points.Span.Sort(pointComparer.Compare); 151 | 152 | TargetPointsFromOffsets(points, center); 153 | 154 | RandomizeBandsTargetPoints(points, randomSeed); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | 244 | # SQL Server files 245 | *.mdf 246 | *.ldf 247 | *.ndf 248 | 249 | # Business Intelligence projects 250 | *.rdl.data 251 | *.bim.layout 252 | *.bim_*.settings 253 | *.rptproj.rsuser 254 | 255 | # Microsoft Fakes 256 | FakesAssemblies/ 257 | 258 | # GhostDoc plugin setting file 259 | *.GhostDoc.xml 260 | 261 | # Node.js Tools for Visual Studio 262 | .ntvs_analysis.dat 263 | node_modules/ 264 | 265 | # Visual Studio 6 build log 266 | *.plg 267 | 268 | # Visual Studio 6 workspace options file 269 | *.opt 270 | 271 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 272 | *.vbw 273 | 274 | # Visual Studio LightSwitch build output 275 | **/*.HTMLClient/GeneratedArtifacts 276 | **/*.DesktopClient/GeneratedArtifacts 277 | **/*.DesktopClient/ModelManifest.xml 278 | **/*.Server/GeneratedArtifacts 279 | **/*.Server/ModelManifest.xml 280 | _Pvt_Extensions 281 | 282 | # Paket dependency manager 283 | .paket/paket.exe 284 | paket-files/ 285 | 286 | # FAKE - F# Make 287 | .fake/ 288 | 289 | # JetBrains Rider 290 | .idea/ 291 | *.sln.iml 292 | 293 | # CodeRush 294 | .cr/ 295 | 296 | # Python Tools for Visual Studio (PTVS) 297 | __pycache__/ 298 | *.pyc 299 | 300 | # Cake - Uncomment if you are using it 301 | # tools/** 302 | # !tools/packages.config 303 | 304 | # Tabs Studio 305 | *.tss 306 | 307 | # Telerik's JustMock configuration file 308 | *.jmconfig 309 | 310 | # BizTalk build output 311 | *.btp.cs 312 | *.btm.cs 313 | *.odx.cs 314 | *.xsd.cs 315 | 316 | # OpenCover UI analysis results 317 | OpenCover/ 318 | 319 | # Azure Stream Analytics local run output 320 | ASALocalRun/ 321 | 322 | # MSBuild Binary and Structured Log 323 | *.binlog 324 | 325 | # NVidia Nsight GPU debugger configuration file 326 | *.nvuser 327 | 328 | # MFractors (Xamarin productivity tool) working folder 329 | .mfractor/ 330 | /*.diagsession 331 | -------------------------------------------------------------------------------- /src/ContentAwareFillEffect.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet; 24 | using PaintDotNet.AppModel; 25 | using PaintDotNet.Effects; 26 | using PaintDotNet.Imaging; 27 | using PaintDotNet.Rendering; 28 | using System; 29 | using System.Drawing; 30 | 31 | namespace ContentAwareFill 32 | { 33 | [PluginSupportInfo(typeof(PluginSupportInfo))] 34 | public sealed class ContentAwareFillEffect : BitmapEffect 35 | { 36 | private bool repeatEffect; 37 | #pragma warning disable CA2213 // Disposable fields should be disposed 38 | private IBitmap output; 39 | private IBitmapSource sourceBitmap; 40 | #pragma warning restore CA2213 // Disposable fields should be disposed 41 | 42 | internal static string StaticName 43 | { 44 | get 45 | { 46 | return "Content Aware Fill"; 47 | } 48 | } 49 | 50 | internal static Bitmap StaticImage 51 | { 52 | get 53 | { 54 | return new Bitmap(typeof(ContentAwareFillEffect), PluginIconUtil.GetIconResourceForDpi(UIScaleFactor.Current.Dpi)); 55 | } 56 | } 57 | 58 | public ContentAwareFillEffect() : base(StaticName, StaticImage, "Selection", BitmapEffectOptions.Create() with { IsConfigurable = true }) 59 | { 60 | this.repeatEffect = true; 61 | } 62 | 63 | protected override IEffectConfigForm OnCreateConfigForm() 64 | { 65 | this.repeatEffect = false; 66 | 67 | return new ContentAwareFillConfigDialog(); 68 | } 69 | 70 | protected override void OnDispose(bool disposing) 71 | { 72 | if (disposing) 73 | { 74 | DisposableUtil.Free(ref this.output); 75 | DisposableUtil.Free(ref this.sourceBitmap); 76 | } 77 | 78 | base.OnDispose(disposing); 79 | } 80 | 81 | /// 82 | /// Determines whether the whole image is selected. 83 | /// 84 | /// The effect environment. 85 | /// 86 | /// true if the whole image is selected; otherwise, false. 87 | /// 88 | /// is null. 89 | internal static bool IsWholeImageSelected(IEffectEnvironment environment) 90 | { 91 | ArgumentNullException.ThrowIfNull(environment); 92 | 93 | RectInt32 documentBounds = new(Point2Int32.Zero, environment.Document.Size); 94 | 95 | bool wholeImageSelected = environment.Selection.RenderBounds == documentBounds; 96 | 97 | if (wholeImageSelected) 98 | { 99 | int imageWidth = documentBounds.Width; 100 | 101 | foreach (RectInt32 scan in environment.Selection.RenderScans) 102 | { 103 | // The scan rectangle height is not checked because Paint.NET 104 | // may split a tall rectangle into smaller chunks. 105 | if (scan.X > 0 || scan.Width < imageWidth) 106 | { 107 | // The rectangle does not span the entire width of the image. 108 | wholeImageSelected = false; 109 | break; 110 | } 111 | } 112 | } 113 | 114 | return wholeImageSelected; 115 | } 116 | 117 | protected override void OnSetToken(ContentAwareFillConfigToken token) 118 | { 119 | if (this.repeatEffect) 120 | { 121 | if (token.Output != null) 122 | { 123 | token.Output.Dispose(); 124 | token.Output = null; 125 | } 126 | 127 | // This plugin does not support processing a selection of the whole image, it needs some unselected pixels 128 | // to replace the contents of the selected area. 129 | // When there is no active selection Paint.NET acts as if the whole image/layer is selected. 130 | if (!IsWholeImageSelected(this.Environment)) 131 | { 132 | try 133 | { 134 | using (ResynthesizerRunner resynthesizer = new(this.Environment, this.Services)) 135 | { 136 | resynthesizer.SetParameters(token.SampleSize, 137 | token.SampleFrom, 138 | token.FillDirection, 139 | token.Seed); 140 | 141 | token.Output = resynthesizer.Run(this.CancellationToken); 142 | } 143 | } 144 | catch (ResynthesizerException ex) 145 | { 146 | this.Services.GetService().ShowErrorDialog(null, ex); 147 | } 148 | } 149 | } 150 | 151 | if (token.Output != null) 152 | { 153 | this.output ??= this.Environment.ImagingFactory.CreateBitmap(this.Environment.Document.Size); 154 | this.output = token.Output.ToBitmap(); 155 | } 156 | else 157 | { 158 | this.sourceBitmap ??= this.Environment.GetSourceBitmapBgra32(); 159 | } 160 | 161 | base.OnSetToken(token); 162 | } 163 | 164 | protected override unsafe void OnRender(IBitmapEffectOutput output) 165 | { 166 | if (this.output != null) 167 | { 168 | using (IBitmapLock src = this.output.Lock(output.Bounds, BitmapLockOptions.Read)) 169 | using (IBitmapLock dst = output.LockBgra32()) 170 | { 171 | src.AsRegionPtr().CopyTo(dst.AsRegionPtr()); 172 | } 173 | } 174 | else 175 | { 176 | using (IBitmapLock dst = output.LockBgra32()) 177 | { 178 | this.sourceBitmap.CopyPixels(dst.Buffer, dst.BufferStride, dst.BufferSize, output.Bounds); 179 | } 180 | } 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | There is no active selection or the entire image is selected. 122 | 123 | This plugin requires that a portion of the image remain unselected so that it can replace the contents of the selection with pixels that are the closest match in the unselected area. 124 | 125 | 126 | The source region is empty. Does the area outside the selection include any non-transparent pixels? 127 | 128 | 129 | The target layer is empty. Does the selection include any non-transparent pixels? 130 | 131 | 132 | 133 | ..\Resources\Icons\ResetIcon-96.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 134 | 135 | 136 | Ready 137 | 138 | 139 | Rendering... 140 | 141 | 142 | Initializing... 143 | 144 | -------------------------------------------------------------------------------- /src/ResynthesizerRunner.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using PaintDotNet; 24 | using PaintDotNet.Direct2D1; 25 | using PaintDotNet.Effects; 26 | using PaintDotNet.Imaging; 27 | using PaintDotNet.Rendering; 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Threading; 31 | 32 | namespace ContentAwareFill 33 | { 34 | internal sealed class ResynthesizerRunner : Disposable 35 | { 36 | private IBitmap sourceMask; 37 | private IBitmap targetMask; 38 | private int sampleSize; 39 | private SampleSource sampleFrom; 40 | private FillDirection fillDirection; 41 | private int seed; 42 | private readonly IEffectEnvironment environment; 43 | private readonly IServiceProvider serviceProvider; 44 | #pragma warning disable CA2213 // Disposable fields should be disposed 45 | private readonly IImagingFactory imagingFactory; 46 | #pragma warning restore CA2213 // Disposable fields should be disposed 47 | 48 | /// 49 | /// Initializes a new instance of the class. 50 | /// 51 | /// The source. 52 | /// The service provider. 53 | /// 54 | /// is null. 55 | /// or 56 | /// is null. 57 | /// 58 | public ResynthesizerRunner(IEffectEnvironment environment, IServiceProvider serviceProvider) 59 | { 60 | ArgumentNullException.ThrowIfNull(environment); 61 | ArgumentNullException.ThrowIfNull(serviceProvider); 62 | 63 | this.sourceMask = null; 64 | this.targetMask = null; 65 | this.sampleSize = 50; 66 | this.sampleFrom = SampleSource.Sides; 67 | this.fillDirection = FillDirection.InwardToCenter; 68 | this.seed = Resynthesizer.DefaultSeed; 69 | this.environment = environment; 70 | this.serviceProvider = serviceProvider; 71 | this.imagingFactory = serviceProvider.GetService(); 72 | } 73 | 74 | /// 75 | /// Runs the Resynthesizer command. 76 | /// 77 | /// The cancellation token. 78 | /// The progress callback. 79 | /// 80 | /// The output if Resynthesizer completed successfully; otherwise, if it was canceled. 81 | /// 82 | /// Unsupported SampleFrom enumeration value. 83 | public IBitmap Run(CancellationToken cancellationToken, Action progressCallback = null) 84 | { 85 | IBitmap output; 86 | try 87 | { 88 | RectInt32 expandedBounds = RenderSourceMask(cancellationToken); 89 | RectInt32 originalBounds = this.environment.Selection.RenderBounds; 90 | 91 | this.targetMask ??= this.environment.Selection.MaskBitmap.ToBitmap(); 92 | 93 | SizeInt32 croppedSourceSize = this.sampleFrom switch 94 | { 95 | SampleSource.Sides => new SizeInt32(expandedBounds.X + expandedBounds.Width, originalBounds.Y + originalBounds.Height), 96 | SampleSource.TopAndBottom => new SizeInt32(originalBounds.X + originalBounds.Width, expandedBounds.Y + expandedBounds.Height), 97 | SampleSource.AllAround => new SizeInt32(expandedBounds.X + expandedBounds.Width, expandedBounds.Y + expandedBounds.Height), 98 | _ => throw new InvalidOperationException("Unsupported SampleFrom enumeration value: " + this.sampleFrom.ToString()), 99 | }; 100 | 101 | MatchContextType matchContext = GetMatchContextType(); 102 | 103 | using (Resynthesizer synth = new(matchContext, 104 | this.seed, 105 | this.environment.GetSourceBitmapBgra32(), 106 | this.sourceMask, 107 | expandedBounds, 108 | croppedSourceSize, 109 | this.targetMask, 110 | progressCallback, 111 | this.imagingFactory, 112 | cancellationToken)) 113 | { 114 | synth.ContentAwareFill(); 115 | output = synth.Target.ToBitmap(); 116 | } 117 | } 118 | catch (OperationCanceledException) 119 | { 120 | output = null; 121 | } 122 | 123 | return output; 124 | } 125 | 126 | /// 127 | /// Sets the parameters. 128 | /// 129 | /// The sample area size. 130 | /// The area of the selection to sample. 131 | /// The direction to fill the generated image. 132 | /// The seed to use for the random number generation. 133 | /// 134 | /// must be positive. 135 | /// or 136 | /// is not a valid value. 137 | /// or 138 | /// is not a valid value. 139 | /// or 140 | /// must be positive. 141 | /// 142 | public void SetParameters(int sampleSize, 143 | SampleSource sampleFrom, 144 | FillDirection fillDirection, 145 | int seed) 146 | { 147 | if (sampleSize < 0) 148 | { 149 | throw new ArgumentOutOfRangeException(nameof(sampleSize), "Must be positive."); 150 | } 151 | 152 | if (sampleFrom < SampleSource.AllAround || sampleFrom > SampleSource.TopAndBottom) 153 | { 154 | throw new ArgumentOutOfRangeException(nameof(sampleFrom)); 155 | } 156 | 157 | if (fillDirection < FillDirection.Random || fillDirection > FillDirection.OutwardFromCenter) 158 | { 159 | throw new ArgumentOutOfRangeException(nameof(fillDirection)); 160 | } 161 | 162 | if (seed < 0) 163 | { 164 | throw new ArgumentOutOfRangeException(nameof(seed), "Must be positive."); 165 | } 166 | 167 | this.sampleSize = sampleSize; 168 | this.sampleFrom = sampleFrom; 169 | this.fillDirection = fillDirection; 170 | this.seed = seed; 171 | } 172 | 173 | protected override void Dispose(bool disposing) 174 | { 175 | if (disposing) 176 | { 177 | this.targetMask?.Dispose(); 178 | this.sourceMask?.Dispose(); 179 | } 180 | 181 | base.Dispose(disposing); 182 | } 183 | 184 | /// 185 | /// Gets the for the specified sampling options. 186 | /// 187 | /// 188 | /// A for the specified sampling options 189 | /// 190 | private MatchContextType GetMatchContextType() 191 | { 192 | if (this.fillDirection == FillDirection.Random) 193 | { 194 | return MatchContextType.Random; 195 | } 196 | else if (this.fillDirection == FillDirection.InwardToCenter) 197 | { 198 | switch (this.sampleFrom) 199 | { 200 | case SampleSource.AllAround: 201 | return MatchContextType.InwardConcentric; 202 | case SampleSource.Sides: 203 | return MatchContextType.InwardHorizontal; 204 | case SampleSource.TopAndBottom: 205 | return MatchContextType.InwardVertical; 206 | } 207 | } 208 | else 209 | { 210 | switch (this.sampleFrom) 211 | { 212 | case SampleSource.AllAround: 213 | return MatchContextType.OutwardConcentric; 214 | case SampleSource.Sides: 215 | return MatchContextType.OutwardHorizontal; 216 | case SampleSource.TopAndBottom: 217 | return MatchContextType.OutwardVertical; 218 | } 219 | } 220 | 221 | return MatchContextType.None; 222 | } 223 | 224 | private unsafe RectInt32 RenderSourceMask(CancellationToken cancellationToken) 225 | { 226 | this.sourceMask ??= this.imagingFactory.CreateBitmap(this.environment.Document.Size); 227 | 228 | RectInt32 maskBounds = RectInt32.Empty; 229 | 230 | IDirect2DFactory d2dFactory = this.serviceProvider.GetService(); 231 | 232 | using (IDeviceContext deviceContext = d2dFactory.CreateBitmapDeviceContext(this.sourceMask)) 233 | { 234 | // PrimitiveBlend.Copy is required for Direct2D to mask out the original selection. 235 | deviceContext.PrimitiveBlend = PrimitiveBlend.Copy; 236 | 237 | using (ISolidColorBrush selectedRegionBrush = deviceContext.CreateSolidColorBrush(SrgbColors.White)) 238 | using (ISolidColorBrush unselectedRegionBrush = deviceContext.CreateSolidColorBrush(SrgbColors.Transparent)) 239 | using (deviceContext.UseBeginDraw()) 240 | { 241 | IReadOnlyList selectionRects = this.environment.Selection.RenderScans; 242 | RectInt32 surfaceBounds = this.sourceMask.Bounds(); 243 | 244 | deviceContext.Clear(SrgbColors.Transparent); 245 | 246 | foreach (RectInt32 rect in selectionRects) 247 | { 248 | cancellationToken.ThrowIfCancellationRequested(); 249 | 250 | RectInt32 expandedRect = RectInt32.Inflate(rect, this.sampleSize, this.sampleSize); 251 | RectInt32 selectedArea = RectInt32.Intersect(expandedRect, surfaceBounds); 252 | 253 | deviceContext.FillRectangle(selectedArea, selectedRegionBrush); 254 | 255 | maskBounds = RectInt32.Union(maskBounds, selectedArea); 256 | } 257 | 258 | // Exclude the pixels in the original selection. 259 | // This is does in a second pass because it would be overwritten by the enlarged scans 260 | // when there is more than one scan rectangle. 261 | foreach (RectInt32 rect in selectionRects) 262 | { 263 | cancellationToken.ThrowIfCancellationRequested(); 264 | 265 | deviceContext.FillRectangle(rect, unselectedRegionBrush); 266 | } 267 | } 268 | } 269 | 270 | return maskBounds; 271 | } 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /src/ContentAwareFillConfigDialog.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of pdn-content-aware-fill, A Resynthesizer-based 3 | * content aware fill Effect plug-in for Paint.NET. 4 | * 5 | * Copyright (C) 2018, 2020, 2021, 2022, 2023, 2024, 2025 Nicholas Hayes 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | * 21 | */ 22 | 23 | using ContentAwareFill.Properties; 24 | using PaintDotNet; 25 | using PaintDotNet.AppModel; 26 | using PaintDotNet.Effects; 27 | using PaintDotNet.Imaging; 28 | using System; 29 | using System.ComponentModel; 30 | using System.Drawing; 31 | using System.Threading; 32 | using System.Windows.Forms; 33 | 34 | namespace ContentAwareFill 35 | { 36 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 37 | "Style", 38 | "IDE1006:Naming Styles", 39 | Justification = "The VS designer generates methods that start with a lower case letter.")] 40 | internal partial class ContentAwareFillConfigDialog : EffectConfigForm 41 | { 42 | private int ignoreTokenChangedEventCount; 43 | private bool formClosePending; 44 | private bool restartBackgroundWorker; 45 | private bool selectionValid; 46 | private bool ranFirstAutoRender; 47 | private bool setRenderingStatusText; 48 | private IBitmap output; 49 | private ResynthesizerRunner resynthesizer; 50 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 51 | "Usage", 52 | "CA2213:Disposable fields should be disposed", 53 | Justification = "False positive with the analyzer.")] 54 | private CancellationTokenSource resynthesizerTokenSource; 55 | 56 | public ContentAwareFillConfigDialog() 57 | { 58 | InitializeComponent(); 59 | UI.InitScaling(this); 60 | this.toolStripStatusLabel1.Text = Resources.StatusReadyText; 61 | this.ignoreTokenChangedEventCount = 0; 62 | this.formClosePending = false; 63 | this.selectionValid = false; 64 | this.ranFirstAutoRender = false; 65 | this.output = null; 66 | this.resynthesizer = null; 67 | this.Text += " v" + typeof(ContentAwareFillEffect).Assembly.GetName().Version.ToString(); 68 | 69 | PluginThemingUtil.UpdateControlBackColor(this); 70 | PluginThemingUtil.UpdateControlForeColor(this); 71 | } 72 | 73 | protected override bool UseAppThemeColorsDefault => true; 74 | 75 | protected override void OnBackColorChanged(EventArgs e) 76 | { 77 | base.OnBackColorChanged(e); 78 | 79 | PluginThemingUtil.UpdateControlBackColor(this); 80 | } 81 | 82 | protected override void OnForeColorChanged(EventArgs e) 83 | { 84 | base.OnForeColorChanged(e); 85 | 86 | PluginThemingUtil.UpdateControlForeColor(this); 87 | } 88 | 89 | protected override void OnFormClosing(FormClosingEventArgs e) 90 | { 91 | if (this.backgroundWorker.IsBusy) 92 | { 93 | e.Cancel = true; 94 | this.formClosePending = true; 95 | 96 | if (this.DialogResult == DialogResult.Cancel) 97 | { 98 | this.resynthesizerTokenSource.Cancel(); 99 | } 100 | } 101 | 102 | base.OnFormClosing(e); 103 | } 104 | 105 | protected override void OnLoading() 106 | { 107 | base.OnLoading(); 108 | 109 | UpdateResetButtonIconForDpi(); 110 | } 111 | 112 | protected override void OnShown(EventArgs e) 113 | { 114 | base.OnShown(e); 115 | 116 | // This plugin does not support processing a selection of the whole image, it needs some 117 | // unselected pixels to replace the contents of the selected area. 118 | // When there is no active selection Paint.NET acts as if the whole image/layer is selected. 119 | if (ContentAwareFillEffect.IsWholeImageSelected(this.Environment)) 120 | { 121 | if (ShowErrorMessage(Resources.WholeImageSelected) == DialogResult.OK) 122 | { 123 | Close(); 124 | } 125 | } 126 | else 127 | { 128 | this.selectionValid = true; 129 | 130 | if (this.ignoreTokenChangedEventCount == 0 && this.autoRenderCb.Checked && !this.ranFirstAutoRender) 131 | { 132 | StartBackgroundWorker(); 133 | } 134 | } 135 | } 136 | 137 | private void PushIgnoreTokenChangedEvents() 138 | { 139 | this.ignoreTokenChangedEventCount++; 140 | } 141 | 142 | private void PopIgnoreTokenChangedEvents() 143 | { 144 | this.ignoreTokenChangedEventCount--; 145 | 146 | if (this.ignoreTokenChangedEventCount == 0 && this.autoRenderCb.Checked && this.selectionValid) 147 | { 148 | this.ranFirstAutoRender = true; 149 | StartBackgroundWorker(); 150 | } 151 | } 152 | 153 | private void UpdateConfigToken() 154 | { 155 | if (this.ignoreTokenChangedEventCount == 0 && this.autoRenderCb.Checked) 156 | { 157 | StartBackgroundWorker(); 158 | } 159 | } 160 | 161 | protected override EffectConfigToken OnCreateInitialToken() 162 | { 163 | return new ContentAwareFillConfigToken(50, 164 | SampleSource.Sides, 165 | FillDirection.InwardToCenter, 166 | Resynthesizer.DefaultSeed, 167 | true, 168 | null); 169 | } 170 | 171 | protected override void OnUpdateDialogFromToken(ContentAwareFillConfigToken token) 172 | { 173 | // Call FinishTokenUpdate after the controls are initialized. 174 | PushIgnoreTokenChangedEvents(); 175 | 176 | this.sampleSizeTrackBar.Value = token.SampleSize; 177 | this.sampleFromCombo.SelectedIndex = (int)token.SampleFrom; 178 | this.fillDirectionCombo.SelectedIndex = (int)token.FillDirection; 179 | this.seedUpDown.Value = token.Seed; 180 | this.autoRenderCb.Checked = token.RenderAutomatically; 181 | 182 | PopIgnoreTokenChangedEvents(); 183 | } 184 | 185 | protected override void OnUpdateTokenFromDialog(ContentAwareFillConfigToken token) 186 | { 187 | token.SampleSize = this.sampleSizeTrackBar.Value; 188 | token.SampleFrom = (SampleSource)this.sampleFromCombo.SelectedIndex; 189 | token.FillDirection = (FillDirection)this.fillDirectionCombo.SelectedIndex; 190 | token.Seed = (int)this.seedUpDown.Value; 191 | token.RenderAutomatically = this.autoRenderCb.Checked; 192 | token.Output = this.output; 193 | } 194 | 195 | private void UpdateResetButtonIconForDpi() 196 | { 197 | int dpi = this.DeviceDpi; 198 | 199 | if (dpi > 96) 200 | { 201 | if (dpi <= 120) 202 | { 203 | this.sliderResetButton.Image = new Bitmap(typeof(ContentAwareFillConfigDialog), "Resources.Icons.ResetIcon-120.png"); 204 | } 205 | else if (dpi <= 144) 206 | { 207 | this.sliderResetButton.Image = new Bitmap(typeof(ContentAwareFillConfigDialog), "Resources.Icons.ResetIcon-144.png"); 208 | } 209 | else if (dpi <= 192) 210 | { 211 | this.sliderResetButton.Image = new Bitmap(typeof(ContentAwareFillConfigDialog), "Resources.Icons.ResetIcon-192.png"); 212 | } 213 | else 214 | { 215 | this.sliderResetButton.Image = new Bitmap(typeof(ContentAwareFillConfigDialog), "Resources.Icons.ResetIcon-384.png"); 216 | } 217 | } 218 | } 219 | 220 | private DialogResult ShowErrorMessage(string message) 221 | { 222 | if (this.InvokeRequired) 223 | { 224 | Invoke(new Action((string text) => 225 | this.Services.GetService().ShowErrorDialog(this, text, string.Empty)), 226 | message); 227 | } 228 | else 229 | { 230 | this.Services.GetService().ShowErrorDialog(this, message, string.Empty); 231 | } 232 | 233 | return DialogResult.OK; 234 | } 235 | 236 | private DialogResult ShowErrorMessage(Exception exception) 237 | { 238 | if (this.InvokeRequired) 239 | { 240 | Invoke(new Action((Exception ex) => 241 | this.Services.GetService().ShowErrorDialog(this, ex)), 242 | exception); 243 | } 244 | else 245 | { 246 | this.Services.GetService().ShowErrorDialog(this, exception); 247 | } 248 | 249 | return DialogResult.OK; 250 | } 251 | 252 | private void okButton_Click(object sender, EventArgs e) 253 | { 254 | this.DialogResult = DialogResult.OK; 255 | Close(); 256 | } 257 | 258 | private void cancelButton_Click(object sender, EventArgs e) 259 | { 260 | this.DialogResult = DialogResult.Cancel; 261 | Close(); 262 | } 263 | 264 | private void sampleSizeTrackBar_ValueChanged(object sender, EventArgs e) 265 | { 266 | if (this.sampleSizeTrackBar.Value != (int)this.sampleSizeUpDown.Value) 267 | { 268 | this.sampleSizeUpDown.Value = this.sampleSizeTrackBar.Value; 269 | 270 | UpdateConfigToken(); 271 | } 272 | } 273 | 274 | private void sampleSizeUpDown_ValueChanged(object sender, EventArgs e) 275 | { 276 | if (this.sampleSizeUpDown.Value != this.sampleSizeTrackBar.Value) 277 | { 278 | this.sampleSizeTrackBar.Value = (int)this.sampleSizeUpDown.Value; 279 | 280 | UpdateConfigToken(); 281 | } 282 | } 283 | 284 | private void sampleFromCombo_SelectedIndexChanged(object sender, EventArgs e) 285 | { 286 | UpdateConfigToken(); 287 | } 288 | 289 | private void fillDirectionCombo_SelectedIndexChanged(object sender, EventArgs e) 290 | { 291 | UpdateConfigToken(); 292 | } 293 | 294 | private void sliderResetButton_Click(object sender, EventArgs e) 295 | { 296 | this.sampleSizeTrackBar.Value = 50; 297 | } 298 | 299 | private void donateLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 300 | { 301 | this.Services.GetService().LaunchUrl(this, "https://forums.getpaint.net/index.php?showtopic=112730"); 302 | } 303 | 304 | private void autoRenderCb_CheckedChanged(object sender, EventArgs e) 305 | { 306 | this.applyButton.Enabled = !this.autoRenderCb.Checked; 307 | } 308 | 309 | private void applyButton_Click(object sender, EventArgs e) 310 | { 311 | StartBackgroundWorker(); 312 | } 313 | 314 | private void seedUpDown_ValueChanged(object sender, EventArgs e) 315 | { 316 | UpdateConfigToken(); 317 | } 318 | 319 | private void seedResetButton_Click(object sender, EventArgs e) 320 | { 321 | this.seedUpDown.Value = Resynthesizer.DefaultSeed; 322 | } 323 | 324 | private void seedRandomizeButton_Click(object sender, EventArgs e) 325 | { 326 | this.seedUpDown.Value = Random.Shared.Next(); 327 | } 328 | 329 | private void StartBackgroundWorker() 330 | { 331 | if (this.backgroundWorker.IsBusy) 332 | { 333 | this.restartBackgroundWorker = true; 334 | this.resynthesizerTokenSource.Cancel(); 335 | } 336 | else 337 | { 338 | this.resynthesizer ??= new ResynthesizerRunner(this.Environment, this.Services); 339 | this.resynthesizerTokenSource = new CancellationTokenSource(); 340 | 341 | this.resynthesizer.SetParameters(this.sampleSizeTrackBar.Value, 342 | (SampleSource)this.sampleFromCombo.SelectedIndex, 343 | (FillDirection)this.fillDirectionCombo.SelectedIndex, 344 | (int)this.seedUpDown.Value); 345 | 346 | this.backgroundWorker.RunWorkerAsync(); 347 | } 348 | } 349 | 350 | private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 351 | { 352 | Invoke(() => 353 | { 354 | this.toolStripStatusLabel1.Text = Resources.StatusInitializingText; 355 | this.toolStripProgressBar1.Style = ProgressBarStyle.Marquee; 356 | this.setRenderingStatusText = false; 357 | }); 358 | 359 | BackgroundWorker worker = (BackgroundWorker)sender; 360 | 361 | IBitmap output = this.resynthesizer.Run(this.resynthesizerTokenSource.Token, 362 | worker.ReportProgress); 363 | 364 | if (output != null) 365 | { 366 | e.Result = output; 367 | } 368 | else 369 | { 370 | e.Cancel = true; 371 | } 372 | } 373 | 374 | private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 375 | { 376 | if (!this.setRenderingStatusText) 377 | { 378 | this.setRenderingStatusText = true; 379 | this.toolStripProgressBar1.Style = ProgressBarStyle.Continuous; 380 | this.toolStripStatusLabel1.Text = Resources.StatusRenderingText; 381 | } 382 | 383 | this.toolStripProgressBar1.Value = e.ProgressPercentage; 384 | } 385 | 386 | private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 387 | { 388 | if (this.resynthesizerTokenSource != null) 389 | { 390 | this.resynthesizerTokenSource.Dispose(); 391 | this.resynthesizerTokenSource = null; 392 | } 393 | 394 | if (this.restartBackgroundWorker) 395 | { 396 | this.restartBackgroundWorker = false; 397 | this.resynthesizer.SetParameters(this.sampleSizeTrackBar.Value, 398 | (SampleSource)this.sampleFromCombo.SelectedIndex, 399 | (FillDirection)this.fillDirectionCombo.SelectedIndex, 400 | (int)this.seedUpDown.Value); 401 | this.resynthesizerTokenSource = new CancellationTokenSource(); 402 | 403 | this.backgroundWorker.RunWorkerAsync(); 404 | } 405 | else 406 | { 407 | this.toolStripStatusLabel1.Text = Resources.StatusReadyText; 408 | this.toolStripProgressBar1.Value = 0; 409 | 410 | if (e.Error != null) 411 | { 412 | ShowErrorMessage(e.Error); 413 | } 414 | else 415 | { 416 | if (this.output != null) 417 | { 418 | this.output.Dispose(); 419 | this.output = null; 420 | } 421 | 422 | if (!e.Cancelled) 423 | { 424 | this.output = (IBitmap)e.Result; 425 | UpdateTokenFromDialog(); 426 | } 427 | 428 | if (this.formClosePending) 429 | { 430 | Close(); 431 | } 432 | } 433 | } 434 | } 435 | } 436 | } 437 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | 7 | Everyone is permitted to copy and distribute verbatim copies 8 | of this license document, but changing it is not allowed. 9 | 10 | Preamble 11 | 12 | The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. 13 | 14 | When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. 15 | 16 | To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. 17 | 18 | For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. 19 | 20 | We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. 21 | 22 | Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. 23 | 24 | Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. 25 | 26 | The precise terms and conditions for copying, distribution and modification follow. 27 | 28 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 29 | 30 | 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". 31 | 32 | Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 33 | 34 | 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. 35 | 36 | You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 37 | 38 | 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: 39 | 40 | a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. 41 | 42 | b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. 43 | 44 | c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) 45 | 46 | These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. 47 | 48 | Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. 49 | 50 | In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 51 | 52 | 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: 53 | 54 | a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, 55 | 56 | b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, 57 | 58 | c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) 59 | 60 | The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. 61 | 62 | If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 63 | 64 | 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 65 | 66 | 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 67 | 68 | 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 69 | 70 | 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. 71 | 72 | If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. 73 | 74 | It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. 75 | 76 | This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 77 | 78 | 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 79 | 80 | 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. 81 | 82 | Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 83 | 84 | 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. 85 | 86 | NO WARRANTY 87 | 88 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 89 | 90 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 91 | 92 | END OF TERMS AND CONDITIONS 93 | 94 | How to Apply These Terms to Your New Programs 95 | 96 | If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. 97 | 98 | To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. 99 | 100 | One line to give the program's name and a brief idea of what it does. 101 | Copyright (C) 102 | 103 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 104 | 105 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 106 | 107 | You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 108 | 109 | Also add information on how to contact you by electronic and paper mail. 110 | 111 | If the program is interactive, make it output a short notice like this when it starts in an interactive mode: 112 | 113 | Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. 114 | 115 | The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. 116 | 117 | You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: 118 | 119 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. 120 | 121 | signature of Ty Coon, 1 April 1989 122 | Ty Coon, President of Vice 123 | 124 | This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. -------------------------------------------------------------------------------- /src/ContentAwareFillConfigDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ContentAwareFill 2 | { 3 | partial class ContentAwareFillConfigDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 15 | protected override void OnDispose(bool disposing) 16 | { 17 | if (disposing) 18 | { 19 | if (components != null) 20 | { 21 | components.Dispose(); 22 | components = null; 23 | } 24 | 25 | if (this.resynthesizer != null) 26 | { 27 | this.resynthesizer.Dispose(); 28 | this.resynthesizer = null; 29 | } 30 | 31 | if (this.resynthesizerTokenSource != null) 32 | { 33 | this.resynthesizerTokenSource.Dispose(); 34 | this.resynthesizerTokenSource = null; 35 | } 36 | } 37 | base.OnDispose(disposing); 38 | } 39 | 40 | #region Component Designer generated code 41 | 42 | /// 43 | /// Required method for Designer support - do not modify 44 | /// the contents of this method with the code editor. 45 | /// 46 | private void InitializeComponent() 47 | { 48 | this.cancelButton = new System.Windows.Forms.Button(); 49 | this.okButton = new System.Windows.Forms.Button(); 50 | this.sampleFromCombo = new System.Windows.Forms.ComboBox(); 51 | this.fillDirectionCombo = new System.Windows.Forms.ComboBox(); 52 | this.sampleSizeTrackBar = new System.Windows.Forms.TrackBar(); 53 | this.sampleSizeUpDown = new System.Windows.Forms.NumericUpDown(); 54 | this.sliderResetButton = new System.Windows.Forms.Button(); 55 | this.donateLabel = new System.Windows.Forms.LinkLabel(); 56 | this.autoRenderCb = new System.Windows.Forms.CheckBox(); 57 | this.applyButton = new System.Windows.Forms.Button(); 58 | this.backgroundWorker = new System.ComponentModel.BackgroundWorker(); 59 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 60 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 61 | this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar(); 62 | this.fillDirectionHeader = new HeaderLabel(); 63 | this.sampleFromHeader = new HeaderLabel(); 64 | this.sampleSizeHeader = new HeaderLabel(); 65 | this.seedHeader = new HeaderLabel(); 66 | this.seedUpDown = new System.Windows.Forms.NumericUpDown(); 67 | this.seedResetButton = new System.Windows.Forms.Button(); 68 | this.seedRandomizeButton = new System.Windows.Forms.Button(); 69 | ((System.ComponentModel.ISupportInitialize)this.sampleSizeTrackBar).BeginInit(); 70 | ((System.ComponentModel.ISupportInitialize)this.sampleSizeUpDown).BeginInit(); 71 | this.statusStrip1.SuspendLayout(); 72 | ((System.ComponentModel.ISupportInitialize)this.seedUpDown).BeginInit(); 73 | SuspendLayout(); 74 | // 75 | // cancelButton 76 | // 77 | this.cancelButton.Location = new System.Drawing.Point(251, 256); 78 | this.cancelButton.Name = "cancelButton"; 79 | this.cancelButton.Size = new System.Drawing.Size(75, 23); 80 | this.cancelButton.TabIndex = 0; 81 | this.cancelButton.Text = "Cancel"; 82 | this.cancelButton.UseVisualStyleBackColor = true; 83 | this.cancelButton.Click += cancelButton_Click; 84 | // 85 | // okButton 86 | // 87 | this.okButton.Location = new System.Drawing.Point(170, 256); 88 | this.okButton.Name = "okButton"; 89 | this.okButton.Size = new System.Drawing.Size(75, 23); 90 | this.okButton.TabIndex = 11; 91 | this.okButton.Text = "Ok"; 92 | this.okButton.UseVisualStyleBackColor = true; 93 | this.okButton.Click += okButton_Click; 94 | // 95 | // sampleFromCombo 96 | // 97 | this.sampleFromCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 98 | this.sampleFromCombo.FormattingEnabled = true; 99 | this.sampleFromCombo.Items.AddRange(new object[] { "All Around", "Sides", "Top and Bottom" }); 100 | this.sampleFromCombo.Location = new System.Drawing.Point(12, 88); 101 | this.sampleFromCombo.Name = "sampleFromCombo"; 102 | this.sampleFromCombo.Size = new System.Drawing.Size(152, 23); 103 | this.sampleFromCombo.TabIndex = 4; 104 | this.sampleFromCombo.SelectedIndexChanged += sampleFromCombo_SelectedIndexChanged; 105 | // 106 | // fillDirectionCombo 107 | // 108 | this.fillDirectionCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 109 | this.fillDirectionCombo.FormattingEnabled = true; 110 | this.fillDirectionCombo.Items.AddRange(new object[] { "Random", "Inwards towards center", "Outwards from center" }); 111 | this.fillDirectionCombo.Location = new System.Drawing.Point(12, 135); 112 | this.fillDirectionCombo.Name = "fillDirectionCombo"; 113 | this.fillDirectionCombo.Size = new System.Drawing.Size(152, 23); 114 | this.fillDirectionCombo.TabIndex = 5; 115 | this.fillDirectionCombo.SelectedIndexChanged += fillDirectionCombo_SelectedIndexChanged; 116 | // 117 | // sampleSizeTrackBar 118 | // 119 | this.sampleSizeTrackBar.Location = new System.Drawing.Point(12, 37); 120 | this.sampleSizeTrackBar.Maximum = 100; 121 | this.sampleSizeTrackBar.Minimum = 1; 122 | this.sampleSizeTrackBar.Name = "sampleSizeTrackBar"; 123 | this.sampleSizeTrackBar.Size = new System.Drawing.Size(215, 45); 124 | this.sampleSizeTrackBar.TabIndex = 1; 125 | this.sampleSizeTrackBar.TickFrequency = 5; 126 | this.sampleSizeTrackBar.TickStyle = System.Windows.Forms.TickStyle.None; 127 | this.sampleSizeTrackBar.Value = 50; 128 | this.sampleSizeTrackBar.ValueChanged += sampleSizeTrackBar_ValueChanged; 129 | // 130 | // sampleSizeUpDown 131 | // 132 | this.sampleSizeUpDown.Location = new System.Drawing.Point(233, 37); 133 | this.sampleSizeUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); 134 | this.sampleSizeUpDown.Name = "sampleSizeUpDown"; 135 | this.sampleSizeUpDown.Size = new System.Drawing.Size(61, 23); 136 | this.sampleSizeUpDown.TabIndex = 2; 137 | this.sampleSizeUpDown.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 138 | this.sampleSizeUpDown.Value = new decimal(new int[] { 50, 0, 0, 0 }); 139 | this.sampleSizeUpDown.ValueChanged += sampleSizeUpDown_ValueChanged; 140 | // 141 | // sliderResetButton 142 | // 143 | this.sliderResetButton.Image = Properties.Resources.ResetIcon_96; 144 | this.sliderResetButton.Location = new System.Drawing.Point(300, 37); 145 | this.sliderResetButton.Name = "sliderResetButton"; 146 | this.sliderResetButton.Size = new System.Drawing.Size(22, 20); 147 | this.sliderResetButton.TabIndex = 3; 148 | this.sliderResetButton.UseVisualStyleBackColor = true; 149 | this.sliderResetButton.Click += sliderResetButton_Click; 150 | // 151 | // donateLabel 152 | // 153 | this.donateLabel.AutoSize = true; 154 | this.donateLabel.Location = new System.Drawing.Point(12, 260); 155 | this.donateLabel.Name = "donateLabel"; 156 | this.donateLabel.Size = new System.Drawing.Size(48, 15); 157 | this.donateLabel.TabIndex = 10; 158 | this.donateLabel.TabStop = true; 159 | this.donateLabel.Text = "Donate!"; 160 | this.donateLabel.LinkClicked += donateLabel_LinkClicked; 161 | // 162 | // autoRenderCb 163 | // 164 | this.autoRenderCb.AutoSize = true; 165 | this.autoRenderCb.Checked = true; 166 | this.autoRenderCb.CheckState = System.Windows.Forms.CheckState.Checked; 167 | this.autoRenderCb.Location = new System.Drawing.Point(12, 231); 168 | this.autoRenderCb.Name = "autoRenderCb"; 169 | this.autoRenderCb.Size = new System.Drawing.Size(138, 19); 170 | this.autoRenderCb.TabIndex = 9; 171 | this.autoRenderCb.Text = "Render automatically"; 172 | this.autoRenderCb.UseVisualStyleBackColor = true; 173 | this.autoRenderCb.CheckedChanged += autoRenderCb_CheckedChanged; 174 | // 175 | // applyButton 176 | // 177 | this.applyButton.Enabled = false; 178 | this.applyButton.Location = new System.Drawing.Point(251, 227); 179 | this.applyButton.Name = "applyButton"; 180 | this.applyButton.Size = new System.Drawing.Size(75, 23); 181 | this.applyButton.TabIndex = 10; 182 | this.applyButton.Text = "Apply"; 183 | this.applyButton.UseVisualStyleBackColor = true; 184 | this.applyButton.Click += applyButton_Click; 185 | // 186 | // backgroundWorker 187 | // 188 | this.backgroundWorker.WorkerReportsProgress = true; 189 | this.backgroundWorker.DoWork += backgroundWorker_DoWork; 190 | this.backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; 191 | this.backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; 192 | // 193 | // statusStrip1 194 | // 195 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripStatusLabel1, this.toolStripProgressBar1 }); 196 | this.statusStrip1.Location = new System.Drawing.Point(0, 282); 197 | this.statusStrip1.Name = "statusStrip1"; 198 | this.statusStrip1.Size = new System.Drawing.Size(337, 22); 199 | this.statusStrip1.SizingGrip = false; 200 | this.statusStrip1.TabStop = false; 201 | this.statusStrip1.Text = "statusStrip1"; 202 | // 203 | // toolStripStatusLabel1 204 | // 205 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 206 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); 207 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 208 | // 209 | // toolStripProgressBar1 210 | // 211 | this.toolStripProgressBar1.Name = "toolStripProgressBar1"; 212 | this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16); 213 | // 214 | // fillDirectionHeader 215 | // 216 | this.fillDirectionHeader.ForeColor = System.Drawing.SystemColors.Highlight; 217 | this.fillDirectionHeader.Location = new System.Drawing.Point(12, 115); 218 | this.fillDirectionHeader.Name = "fillDirectionHeader"; 219 | this.fillDirectionHeader.Size = new System.Drawing.Size(310, 14); 220 | this.fillDirectionHeader.TabStop = false; 221 | this.fillDirectionHeader.Text = "Fill direction:"; 222 | // 223 | // sampleFromHeader 224 | // 225 | this.sampleFromHeader.ForeColor = System.Drawing.SystemColors.Highlight; 226 | this.sampleFromHeader.Location = new System.Drawing.Point(12, 63); 227 | this.sampleFromHeader.Name = "sampleFromHeader"; 228 | this.sampleFromHeader.Size = new System.Drawing.Size(310, 14); 229 | this.sampleFromHeader.TabStop = false; 230 | this.sampleFromHeader.Text = "Sample from:"; 231 | // 232 | // sampleSizeHeader 233 | // 234 | this.sampleSizeHeader.ForeColor = System.Drawing.SystemColors.Highlight; 235 | this.sampleSizeHeader.Location = new System.Drawing.Point(12, 17); 236 | this.sampleSizeHeader.Name = "sampleSizeHeader"; 237 | this.sampleSizeHeader.Size = new System.Drawing.Size(310, 14); 238 | this.sampleSizeHeader.TabStop = false; 239 | this.sampleSizeHeader.Text = "Sample area size (in pixels):"; 240 | // 241 | // seedHeader 242 | // 243 | this.seedHeader.ForeColor = System.Drawing.SystemColors.Highlight; 244 | this.seedHeader.Location = new System.Drawing.Point(13, 166); 245 | this.seedHeader.Name = "seedHeader"; 246 | this.seedHeader.Size = new System.Drawing.Size(310, 14); 247 | this.seedHeader.TabStop = false; 248 | this.seedHeader.Text = "Seed"; 249 | // 250 | // seedUpDown 251 | // 252 | this.seedUpDown.Location = new System.Drawing.Point(12, 186); 253 | this.seedUpDown.Maximum = new decimal(new int[] { int.MaxValue, 0, 0, 0 }); 254 | this.seedUpDown.Name = "seedUpDown"; 255 | this.seedUpDown.Size = new System.Drawing.Size(152, 23); 256 | this.seedUpDown.TabIndex = 6; 257 | this.seedUpDown.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 258 | this.seedUpDown.ValueChanged += seedUpDown_ValueChanged; 259 | // 260 | // seedResetButton 261 | // 262 | this.seedResetButton.Image = Properties.Resources.ResetIcon_96; 263 | this.seedResetButton.Location = new System.Drawing.Point(170, 186); 264 | this.seedResetButton.Name = "seedResetButton"; 265 | this.seedResetButton.Size = new System.Drawing.Size(22, 20); 266 | this.seedResetButton.TabIndex = 7; 267 | this.seedResetButton.UseVisualStyleBackColor = true; 268 | this.seedResetButton.Click += seedResetButton_Click; 269 | // 270 | // seedRandomizeButton 271 | // 272 | this.seedRandomizeButton.Location = new System.Drawing.Point(251, 186); 273 | this.seedRandomizeButton.Name = "seedRandomizeButton"; 274 | this.seedRandomizeButton.Size = new System.Drawing.Size(75, 23); 275 | this.seedRandomizeButton.TabIndex = 8; 276 | this.seedRandomizeButton.Text = "Randomize"; 277 | this.seedRandomizeButton.UseVisualStyleBackColor = true; 278 | this.seedRandomizeButton.Click += seedRandomizeButton_Click; 279 | // 280 | // ContentAwareFillConfigDialog 281 | // 282 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); 283 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; 284 | this.ClientSize = new System.Drawing.Size(337, 304); 285 | this.Controls.Add(this.seedRandomizeButton); 286 | this.Controls.Add(this.seedResetButton); 287 | this.Controls.Add(this.seedUpDown); 288 | this.Controls.Add(this.seedHeader); 289 | this.Controls.Add(this.statusStrip1); 290 | this.Controls.Add(this.applyButton); 291 | this.Controls.Add(this.autoRenderCb); 292 | this.Controls.Add(this.donateLabel); 293 | this.Controls.Add(this.fillDirectionHeader); 294 | this.Controls.Add(this.sampleFromHeader); 295 | this.Controls.Add(this.sampleSizeHeader); 296 | this.Controls.Add(this.okButton); 297 | this.Controls.Add(this.cancelButton); 298 | this.Controls.Add(this.sliderResetButton); 299 | this.Controls.Add(this.sampleSizeUpDown); 300 | this.Controls.Add(this.fillDirectionCombo); 301 | this.Controls.Add(this.sampleFromCombo); 302 | this.Controls.Add(this.sampleSizeTrackBar); 303 | this.Name = "ContentAwareFillConfigDialog"; 304 | this.Text = "Content Aware Fill"; 305 | ((System.ComponentModel.ISupportInitialize)this.sampleSizeTrackBar).EndInit(); 306 | ((System.ComponentModel.ISupportInitialize)this.sampleSizeUpDown).EndInit(); 307 | this.statusStrip1.ResumeLayout(false); 308 | this.statusStrip1.PerformLayout(); 309 | ((System.ComponentModel.ISupportInitialize)this.seedUpDown).EndInit(); 310 | ResumeLayout(false); 311 | PerformLayout(); 312 | } 313 | 314 | #endregion 315 | 316 | private System.Windows.Forms.Button cancelButton; 317 | private System.Windows.Forms.Button okButton; 318 | private System.Windows.Forms.ComboBox sampleFromCombo; 319 | private System.Windows.Forms.ComboBox fillDirectionCombo; 320 | private System.Windows.Forms.TrackBar sampleSizeTrackBar; 321 | private System.Windows.Forms.NumericUpDown sampleSizeUpDown; 322 | private System.Windows.Forms.Button sliderResetButton; 323 | private HeaderLabel sampleSizeHeader; 324 | private HeaderLabel sampleFromHeader; 325 | private HeaderLabel fillDirectionHeader; 326 | private System.Windows.Forms.LinkLabel donateLabel; 327 | private System.Windows.Forms.CheckBox autoRenderCb; 328 | private System.Windows.Forms.Button applyButton; 329 | private System.ComponentModel.BackgroundWorker backgroundWorker; 330 | private System.Windows.Forms.StatusStrip statusStrip1; 331 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; 332 | private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1; 333 | private HeaderLabel seedHeader; 334 | private System.Windows.Forms.NumericUpDown seedUpDown; 335 | private System.Windows.Forms.Button seedResetButton; 336 | private System.Windows.Forms.Button seedRandomizeButton; 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /src/Resources/src/ContentAwareFill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | image/svg+xml 7 | 8 | 9 | 10 | Sandwitch 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | --------------------------------------------------------------------------------