├── PhotoEditor
├── Assets
│ ├── bg1.png
│ ├── StoreLogo.png
│ ├── SplashScreen.scale-200.png
│ ├── LockScreenLogo.scale-200.png
│ ├── Square44x44Logo.scale-200.png
│ ├── Wide310x150Logo.scale-200.png
│ ├── Square150x150Logo.scale-200.png
│ └── Square44x44Logo.targetsize-24_altform-unplated.png
├── packages.config
├── pch.cpp
├── App.idl
├── App.xaml
├── MainPage.idl
├── Package.appxmanifest
├── App.h
├── DetailPage.idl
├── Photo.idl
├── PhotoEditor.vcxproj.filters
├── Photo.cpp
├── pch.h
├── App.cpp
├── MainPage.h
├── Photo.h
├── MainPage.xaml
├── DetailPage.h
├── PhotoEditor.vcxproj
├── MainPage.cpp
├── DetailPage.cpp
└── DetailPage.xaml
├── Screenshots
└── PhotoEditorBanner.png
├── CONTRIBUTING.md
├── LICENSE.md
├── PhotoEditor.sln
├── .gitattributes
├── SECURITY.md
├── .gitignore
└── README.md
/PhotoEditor/Assets/bg1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/bg1.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/Screenshots/PhotoEditorBanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/Screenshots/PhotoEditorBanner.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/PhotoEditor/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/Windows-appsample-photo-editor/HEAD/PhotoEditor/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/PhotoEditor/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.microsoft.com.
6 |
7 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
--------------------------------------------------------------------------------
/PhotoEditor/pch.cpp:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #include "pch.h"
26 |
--------------------------------------------------------------------------------
/PhotoEditor/App.idl:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | namespace PhotoEditor
26 | {
27 | }
--------------------------------------------------------------------------------
/PhotoEditor/App.xaml:
--------------------------------------------------------------------------------
1 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/PhotoEditor/MainPage.idl:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | namespace PhotoEditor
26 | {
27 | runtimeclass MainPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged
28 | {
29 | MainPage();
30 | Windows.Foundation.Collections.IVector Photos{ get; };
31 | Windows.Foundation.IAsyncAction StartConnectedAnimationForBackNavigation();
32 | }
33 | }
--------------------------------------------------------------------------------
/PhotoEditor/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | PhotoEditorCppWinRT
7 | Microsoft
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/PhotoEditor/App.h:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #pragma once
26 | #include "App.xaml.g.h"
27 |
28 | namespace winrt::PhotoEditor::implementation
29 | {
30 | struct App : public AppT
31 | {
32 | App();
33 | Windows::UI::Xaml::Controls::Frame CreateRootFrame();
34 |
35 | void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&);
36 | void OnNavigationFailed(IInspectable const&, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs const&);
37 | };
38 | }
39 |
--------------------------------------------------------------------------------
/PhotoEditor/DetailPage.idl:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | import "Photo.idl";
26 |
27 | namespace PhotoEditor
28 | {
29 | runtimeclass DetailPage : Windows.UI.Xaml.Controls.Page
30 | {
31 | DetailPage();
32 | Photo Item;
33 | void ResetColorEffects();
34 | void ResetLightEffects();
35 | void ResetBlurEffects();
36 | void ResetSepiaEffects();
37 | void FitToScreen();
38 | void ShowActualSize();
39 | void UpdateZoomState();
40 | void UpdateEffectBrush(String var);
41 | void ResetEffects();
42 | }
43 | }
--------------------------------------------------------------------------------
/PhotoEditor/Photo.idl:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | namespace PhotoEditor
26 | {
27 | runtimeclass Photo : Windows.UI.Xaml.Data.INotifyPropertyChanged
28 | {
29 | Photo();
30 | Photo(Windows.Storage.FileProperties.ImageProperties props, Windows.Storage.StorageFile imageFile, String name, String type);
31 | Windows.Storage.StorageFile ImageFile{ get; };
32 | Windows.Storage.FileProperties.ImageProperties ImageProperties{ get; };
33 | String ImageName{ get; };
34 | String ImageFileType{ get; };
35 | String ImageDimensions{ get; };
36 | String ImageTitle;
37 | Single Exposure;
38 | Single Temperature;
39 | Single Tint;
40 | Single Contrast;
41 | Single Saturation;
42 | Single BlurAmount;
43 | Single Intensity;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PhotoEditor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27130.2027
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhotoEditor", "PhotoEditor\PhotoEditor.vcxproj", "{A7508B85-CF3D-4D77-8442-71255C16F18C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|ARM = Debug|ARM
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|ARM = Release|ARM
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|ARM.ActiveCfg = Debug|ARM
19 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|ARM.Build.0 = Debug|ARM
20 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|ARM.Deploy.0 = Debug|ARM
21 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|x64.ActiveCfg = Debug|x64
22 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|x64.Build.0 = Debug|x64
23 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|x64.Deploy.0 = Debug|x64
24 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|x86.ActiveCfg = Debug|Win32
25 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|x86.Build.0 = Debug|Win32
26 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Debug|x86.Deploy.0 = Debug|Win32
27 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|ARM.ActiveCfg = Release|ARM
28 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|ARM.Build.0 = Release|ARM
29 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|ARM.Deploy.0 = Release|ARM
30 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|x64.ActiveCfg = Release|x64
31 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|x64.Build.0 = Release|x64
32 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|x64.Deploy.0 = Release|x64
33 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|x86.ActiveCfg = Release|Win32
34 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|x86.Build.0 = Release|Win32
35 | {A7508B85-CF3D-4D77-8442-71255C16F18C}.Release|x86.Deploy.0 = Release|Win32
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | GlobalSection(ExtensibilityGlobals) = postSolution
41 | SolutionGuid = {484FD872-8061-4A4E-9DB9-47203B841EA9}
42 | EndGlobalSection
43 | EndGlobal
44 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/PhotoEditor/PhotoEditor.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Views
9 |
10 |
11 | Views
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Models
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Assets
39 |
40 |
41 | Assets
42 |
43 |
44 | Assets
45 |
46 |
47 | Assets
48 |
49 |
50 | Assets
51 |
52 |
53 | Assets
54 |
55 |
56 | Assets
57 |
58 |
59 | Assets
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | {e48dc53e-40b1-40cb-970a-f89935452892}
74 |
75 |
76 | {d2d82ac2-f140-4cc1-81a6-0c9d62482085}
77 |
78 |
79 | {3bbb5a26-09fb-4f10-ad8e-92f739beaf01}
80 |
81 |
82 |
--------------------------------------------------------------------------------
/PhotoEditor/Photo.cpp:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #include "pch.h"
26 | #include "Photo.h"
27 | #include
28 |
29 | using namespace winrt;
30 | using namespace std;
31 | using namespace Windows::UI::Xaml;
32 | using namespace Windows::Storage;
33 | using namespace Windows::Foundation;
34 | using namespace Windows::UI::Xaml::Media::Imaging;
35 | using namespace Windows::Storage::Streams;
36 |
37 | namespace winrt::PhotoEditor::implementation
38 | {
39 | IAsyncOperation Photo::GetImageThumbnailAsync() const
40 | {
41 | auto thumbnail = co_await m_imageFile.GetThumbnailAsync(FileProperties::ThumbnailMode::PicturesView);
42 | BitmapImage bitmapImage{};
43 | bitmapImage.SetSource(thumbnail);
44 | thumbnail.Close();
45 | co_return bitmapImage;
46 | }
47 |
48 | IAsyncOperation Photo::GetImageSourceAsync() const
49 | {
50 | IRandomAccessStream stream{ co_await ImageFile().OpenAsync(FileAccessMode::Read) };
51 | BitmapImage bitmap{};
52 | bitmap.SetSource(stream);
53 | co_return bitmap;
54 | }
55 |
56 | hstring Photo::ImageDimensions() const
57 | {
58 | wstringstream stringStream;
59 | stringStream << m_imageProperties.Width() << " x " << m_imageProperties.Height();
60 | wstring str = stringStream.str();
61 | return static_cast(str);
62 | }
63 |
64 | void Photo::ImageTitle(hstring const& value)
65 | {
66 | if (m_imageProperties.Title() != value)
67 | {
68 | m_imageProperties.Title(value);
69 | auto ignoreResult = m_imageProperties.SavePropertiesAsync();
70 | RaisePropertyChanged(L"ImageTitle");
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/PhotoEditor/pch.h:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #pragma once
26 |
27 | // This is required because we are using std::min and std::max, otherwise
28 | // we have a collision with min and max macros being defined elsewhere.
29 | #define NOMINMAX
30 |
31 | // This is required otherwise VSDESIGNER will have linker errors.
32 | #define _VSDESIGNER_DONT_LOAD_AS_DLL
33 |
34 | // These are required because XAML compiler assumes these are included.
35 | #include
36 | #include
37 |
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 | #include
53 | #include
54 | #include
55 | #include
56 | #include
57 | #include
58 | #include
59 | #include
60 | #include
61 | #include
62 | #include
63 | #include
64 | #include
65 | #include
66 | #include
67 | #include
68 |
--------------------------------------------------------------------------------
/PhotoEditor/App.cpp:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #include "pch.h"
26 |
27 | #include "App.h"
28 | #include "MainPage.h"
29 |
30 | using namespace winrt;
31 | using namespace Windows::ApplicationModel::Activation;
32 | using namespace Windows::UI::Xaml;
33 | using namespace Windows::UI::Xaml::Controls;
34 | using namespace Windows::UI::Xaml::Navigation;
35 | using namespace PhotoEditor;
36 | using namespace PhotoEditor::implementation;
37 |
38 | ///
39 | /// Initializes the singleton application object. This is the first line of authored code
40 | /// executed, and as such is the logical equivalent of main() or WinMain().
41 | ///
42 | App::App()
43 | {
44 | InitializeComponent();
45 |
46 | #if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
47 | UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e)
48 | {
49 | if (IsDebuggerPresent())
50 | {
51 | auto errorMessage = e.Message();
52 | __debugbreak();
53 | }
54 | });
55 | #endif
56 | }
57 |
58 | ///
59 | /// Invoked when the application is launched normally by the end user. Other entry points
60 | /// will be used such as when the application is launched to open a specific file.
61 | ///
62 | /// Details about the launch request and process.
63 | void App::OnLaunched(LaunchActivatedEventArgs const&)
64 | {
65 | Frame rootFrame = CreateRootFrame();
66 | if (!rootFrame.Content())
67 | {
68 | rootFrame.Navigate(xaml_typename());
69 | }
70 |
71 | Window::Current().Activate();
72 | }
73 |
74 | Frame App::CreateRootFrame()
75 | {
76 | Frame rootFrame{ nullptr };
77 | auto content = Window::Current().Content();
78 | if (content)
79 | {
80 | rootFrame = content.try_as();
81 | }
82 |
83 | // Don't repeat app initialization when the Window already has content,
84 | // just ensure that the window is active
85 | if (!rootFrame)
86 | {
87 | // Create a Frame to act as the navigation context
88 | rootFrame = Frame();
89 |
90 | rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });
91 |
92 | // Place the frame in the current Window
93 | Window::Current().Content(rootFrame);
94 | }
95 |
96 | return rootFrame;
97 | }
98 |
99 | ///
100 | /// Invoked when Navigation to a certain page fails
101 | ///
102 | /// The Frame that failed navigation
103 | /// Details about the navigation failure
104 | void App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e)
105 | {
106 | throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name);
107 | }
108 |
--------------------------------------------------------------------------------
/PhotoEditor/MainPage.h:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #pragma once
26 | #include "MainPage.g.h"
27 |
28 | namespace winrt::PhotoEditor::implementation
29 | {
30 | struct MainPage : MainPageT
31 | {
32 | MainPage();
33 |
34 | // Retreives collection of Photo objects for thumbnail view.
35 | Windows::Foundation::Collections::IVector Photos() const
36 | {
37 | return m_photos;
38 | }
39 |
40 | // Event handlers for loading and rendering images.
41 | Windows::Foundation::IAsyncAction OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs);
42 | Windows::Foundation::IAsyncAction OnContainerContentChanging(Windows::UI::Xaml::Controls::ListViewBase, Windows::UI::Xaml::Controls::ContainerContentChangingEventArgs);
43 |
44 | // Animation for navigation back from DetailPage view.
45 | Windows::Foundation::IAsyncAction StartConnectedAnimationForBackNavigation();
46 |
47 | // Property changed notifications.
48 | event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const&);
49 | void PropertyChanged(event_token const&);
50 |
51 | // Event handler.
52 | void ImageGridView_ItemClick(Windows::Foundation::IInspectable const, Windows::UI::Xaml::Controls::ItemClickEventArgs const);
53 |
54 | private:
55 | // Functions for image loading and animation.
56 | Windows::Foundation::IAsyncAction GetItemsAsync();
57 | Windows::UI::Composition::CompositionAnimationGroup CreateOffsetAnimation();
58 | Windows::Foundation::IAsyncOperation LoadImageInfoAsync(Windows::Storage::StorageFile);
59 |
60 | // Backing field for Photo collection.
61 | Windows::Foundation::Collections::IVector m_photos{ nullptr };
62 |
63 | // Field to store selected Photo for later back navigation.
64 | PhotoEditor::Photo m_persistedItem{ nullptr };
65 |
66 | // Collection of animations for element visuals for reorder animation.
67 | Windows::UI::Composition::ImplicitAnimationCollection m_elementImplicitAnimation{ nullptr };
68 |
69 | // Field to store page Compositor for creation of types in the Windows.UI.Composition namespace.
70 | Windows::UI::Composition::Compositor m_compositor{ nullptr };
71 |
72 | // Event
73 | event> m_handler;
74 |
75 | // Property changed notifications.
76 | void RaisePropertyChanged(hstring const&);
77 | event m_propertyChanged;
78 |
79 | };
80 | }
81 |
82 | namespace winrt::PhotoEditor::factory_implementation
83 | {
84 | struct MainPage : MainPageT
85 | {
86 | };
87 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
262 |
263 | # CPP WinRT
264 | Generated Files/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | page_type: sample
3 | languages:
4 | - cppwinrt
5 | - cpp
6 | products:
7 | - windows
8 | - windows-uwp
9 | statusNotificationTargets:
10 | - codefirst@microsoft.com
11 | ---
12 |
13 |
16 |
17 | # Photo Editor C++/WinRT sample application
18 |
19 | The Photo Editor application is a Universal Windows Platform (UWP) sample that showcases development with the [C++/WinRT](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/intro-to-using-cpp-with-winrt) language projection. The sample application allows you to retrieve photos from the **Pictures** library, and then edit the selected image with assorted photo effects. In the sample's source code, you'll see a number of common practices—such as [data binding](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/binding-property), and [asynchronous actions and operations](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/concurrency)—performed using the C++/WinRT projection.
20 |
21 | > Note - This sample is targeted and tested for Windows 10, version 2004 (10.0; Build 19041), and Visual Studio 2019. If you prefer, you can use project properties to retarget the project(s) to Windows 10, version 1903 (10.0; Build 18362).
22 |
23 | 
24 |
25 | ## Features
26 |
27 | Photo Editor primarily demonstrates:
28 |
29 | - Use of Standard C++17 syntax and libraries with Windows Runtime (WinRT) APIs.
30 | - Use of coroutines, including the use of co_await, co_return, [**IAsyncAction**](https://docs.microsoft.com/uwp/api/windows.foundation.iasyncaction), and [**IAsyncOperation<TResult>**](https://docs.microsoft.com/uwp/api/windows.foundation.iasyncoperation_tresult_).
31 | - Creation and use of custom Windows Runtime class (runtime class) projected types and implementation types. For more info about these terms, see [Consume APIs with C++/WinRT](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/consume-apis) and [Author APIs with C++/WinRT](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/author-apis).
32 | - [Event handling](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/handle-events), including the use of auto-revoking event tokens.
33 | - Use of the external Win2D NuGet package, and [Windows::UI::Composition](https://docs.microsoft.com/uwp/api/windows.ui.composition), for image effects.
34 | - XAML data binding, including the [{x:Bind} markup extension](https://docs.microsoft.com/windows/uwp/xaml-platform/x-bind-markup-extension).
35 | - XAML styling and UI customization, including [connected animations](https://docs.microsoft.com/windows/uwp/design/motion/connected-animation).
36 |
37 | ## Universal Windows Platform development
38 |
39 | ### Prerequisites
40 |
41 | - Windows 10. Minimum: Windows 10, version 1809 (10.0; Build 17763), also known as the Windows 10 October 2018 Update.
42 | - [Windows 10 SDK](https://developer.microsoft.com/windows/downloads/windows-10-sdk). Minimum: Windows SDK version 10.0.17763.0 (Windows 10, version 1809).
43 | - [Visual Studio 2019](https://visualstudio.microsoft.com/downloads/) (or Visual Studio 2017). You can use the free Visual Studio Community Edition to build and run Windows Universal Platform (UWP) apps.
44 | - You'll need to have a collection of images available in your local **Pictures** folder. If there are no images or photos available at that location, the app will not show anything but the background when you run it.
45 |
46 | You can optionally install the [C++/WinRT Visual Studio Extension (VSIX)](https://aka.ms/cppwinrt/vsix). When you open the project, it will install the [Microsoft.Windows.CppWinRT NuGet package](https://www.nuget.org/packages/Microsoft.Windows.CppWinRT/).
47 |
48 | To get the latest updates to Windows and the development tools, and to help shape their development, join
49 | the [Windows Insider Program](https://insider.windows.com).
50 |
51 | ## Running the sample
52 |
53 | The default project is PhotoEditor and you can Start Debugging (F5) or Start Without Debugging (Ctrl+F5) to try it out, just make sure to set the platform target appropriately.
54 | The app will run in the emulator or on physical devices.
55 |
56 | ## Code at a glance
57 |
58 | If you're just interested in code snippets for certain areas, and don't want to browse or run the full sample,
59 | check out the following files.
60 |
61 | A custom runtime class that represents a photo.
62 | * [Photo.idl](PhotoEditor/Photo.idl)
63 | * [Photo.h](PhotoEditor/Photo.h)
64 | * [Photo.cpp](PhotoEditor/Photo.cpp)
65 |
66 | The first page that loads the photos from the Pictures Library and displays a tiled thumbnail view.
67 | * [MainPage.xaml](PhotoEditor/MainPage.xaml)
68 | * [MainPage.idl](PhotoEditor/MainPage.idl)
69 | * [MainPage.h](PhotoEditor/MainPage.h)
70 | * [MainPage.cpp](PhotoEditor/MainPage.cpp)
71 |
72 | Tapping a photo from the MainPage thumbnail view will take you to the photo editor page, where Win2D effects are toggled, set, and chained together.
73 | * [DetailPage.xaml](PhotoEditor/DetailPage.xaml)
74 | * [DetailPage.idl](PhotoEditor/DetailPage.idl)
75 | * [DetailPage.h](PhotoEditor/DetailPage.h)
76 | * [DetailPage.cpp](PhotoEditor/DetailPage.cpp)
77 |
78 | ## Related C++/WinRT documentation and blogs.
79 | * [C++/WinRT UWP conceptual documentation](https://docs.microsoft.com/windows/uwp/cpp-and-winrt-apis/)
80 | * [C++/WinRT base.h reference documentation](https://docs.microsoft.com/uwp/cpp-ref-for-winrt/winrt)
81 | * [ModernCpp blog](https://moderncpp.com/)
82 |
83 | ## Related XAML documentation and code samples.
84 | * [Controls and patterns for UWP apps](https://docs.microsoft.com/windows/uwp/controls-and-patterns/index)
85 | * [Layout for UWP apps](https://docs.microsoft.com/windows/uwp/layout/)
86 | * [Data binding in depth](https://docs.microsoft.com/windows/uwp/data-binding/data-binding-in-depth)
87 | * [UWP style guide](https://docs.microsoft.com/windows/uwp/style/)
88 | * [Visual layer](https://docs.microsoft.com/windows/uwp/composition/visual-layer)
89 | * [ListView and GridView data virtualization](https://docs.microsoft.com/windows/uwp/debug-test-perf/listview-and-gridview-data-optimization)
90 | * [Data virtualization sample](https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/XamlDataVirtualization)
91 |
92 | ## External libraries used in this sample
93 |
94 | * [Win2D](https://github.com/Microsoft/Win2D)
95 |
96 | ## Changing the project's target platform version
97 |
98 | If you build the project on a given target platform version (`TargetPlatformVersion` in the project file), and then you retarget and rebuild, you may see this error message in Visual Studio: "error MIDL2003: [msg]redefinition [context]: ". If you do, then here are some options to resolve the issue.
99 |
100 | - Sometimes, the resolution is as simple as deleting the file `\Windows-appsample-photo-editor\PhotoEditor\\XamlMetaDataProvider.idl`, and rebuilding.
101 | - If that doesn't clear the issue, then you can try deleting all temporary/generated folders and files, and rebuilding.
102 | - If you haven't made changes, then you can alternatively re-clone the repo, re-target, and build.
103 |
--------------------------------------------------------------------------------
/PhotoEditor/Photo.h:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #pragma once
26 |
27 | #include "Photo.g.h"
28 |
29 | namespace winrt::PhotoEditor::implementation
30 | {
31 | struct Photo : PhotoT
32 | {
33 | Photo() = default;
34 |
35 | Photo(Windows::Storage::FileProperties::ImageProperties const& props,
36 | Windows::Storage::StorageFile const& imageFile,
37 | hstring const& name,
38 | hstring const& type) :
39 | m_imageProperties(props),
40 | m_imageName(name),
41 | m_imageFileType(type),
42 | m_imageFile(imageFile)
43 | {
44 | }
45 |
46 | // Gets the thumbnail of current image file (m_imageFile).
47 | Windows::Foundation::IAsyncOperation GetImageThumbnailAsync() const;
48 |
49 | // Gets the full image of the current image file (m_imageFile).
50 | Windows::Foundation::IAsyncOperation GetImageSourceAsync() const;
51 |
52 | // File and information properties.
53 | Windows::Storage::StorageFile ImageFile() const
54 | {
55 | return m_imageFile;
56 | }
57 |
58 | Windows::Storage::FileProperties::ImageProperties ImageProperties() const
59 | {
60 | return m_imageProperties;
61 | }
62 |
63 | hstring ImageName() const
64 | {
65 | return m_imageName;
66 | }
67 |
68 | hstring ImageFileType() const
69 | {
70 | return m_imageFileType;
71 | }
72 |
73 | // Gets or sets the image title.
74 | hstring ImageTitle() const
75 | {
76 | return m_imageProperties.Title() == L"" ? m_imageName : m_imageProperties.Title();
77 | }
78 |
79 | void ImageTitle(hstring const& value);
80 |
81 | hstring ImageDimensions() const;
82 |
83 | // Exposure property for light effect.
84 | float Exposure() const
85 | {
86 | return m_exposure;
87 | }
88 |
89 | void Exposure(float value)
90 | {
91 | UpdateValue(L"Exposure", m_exposure, value);
92 | }
93 |
94 | // Temperature property for color effect.
95 | float Temperature() const
96 | {
97 | return m_temperature;
98 | }
99 |
100 | void Temperature(float value)
101 | {
102 | UpdateValue(L"Temperature", m_temperature, value);
103 | }
104 |
105 | // Tint property for tint and contrast effect.
106 | float Tint() const
107 | {
108 | return m_tint;
109 | }
110 |
111 | void Tint(float value)
112 | {
113 | UpdateValue(L"Tint", m_tint, value);
114 | }
115 |
116 | // Contrast property for tin and contrast effect.
117 | float Contrast() const
118 | {
119 | return m_contrast;
120 | }
121 |
122 | void Contrast(float value)
123 | {
124 | UpdateValue(L"Contrast", m_contrast, value);
125 | }
126 |
127 | // Satruration property for saturation effect.
128 | float Saturation() const
129 | {
130 | return m_saturation;
131 | }
132 |
133 | void Saturation(float value)
134 | {
135 | UpdateValue(L"Saturation", m_saturation, value);
136 | }
137 |
138 | // Blur amount for Gaussian blur effect.
139 | float BlurAmount() const
140 | {
141 | return m_blur;
142 | }
143 |
144 | void BlurAmount(float value)
145 | {
146 | UpdateValue(L"BlurAmount", m_blur, value);
147 | }
148 |
149 | // Intensity for sepia effect.
150 | float Intensity() const
151 | {
152 | return m_sepiaIntensity;
153 | }
154 |
155 | void Intensity(float value)
156 | {
157 | UpdateValue(L"Intensity", m_sepiaIntensity, value);
158 | }
159 |
160 | // Property changed notifications.
161 | event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value)
162 | {
163 | return m_propertyChanged.add(value);
164 | }
165 |
166 | void PropertyChanged(event_token const& token)
167 | {
168 | m_propertyChanged.remove(token);
169 | }
170 |
171 | private:
172 | // File and information fields.
173 | Windows::Storage::FileProperties::ImageProperties m_imageProperties{ nullptr };
174 | Windows::Storage::StorageFile m_imageFile{ nullptr };
175 | hstring m_imageName;
176 | hstring m_imageFileType;
177 | hstring m_imageTitle;
178 |
179 | // Fields for image effects.
180 | float m_exposure{ 0 };
181 | float m_temperature{ 0 };
182 | float m_tint{ 0 };
183 | float m_contrast{ 0 };
184 | float m_saturation{ 1 };
185 | float m_blur{ 0 };
186 | float m_sepiaIntensity{ .5f };
187 |
188 | // Size field for image tile size on MainPage.
189 | double m_size{ 250 };
190 |
191 | // Property changed notification.
192 | event m_propertyChanged;
193 |
194 | template
195 | void UpdateValue(hstring const& propertyName, T & var, T value)
196 | {
197 | if (var != value)
198 | {
199 | var = value;
200 | RaisePropertyChanged(propertyName);
201 | }
202 | }
203 |
204 | void RaisePropertyChanged(hstring const& propertyName)
205 | {
206 | m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs(propertyName));
207 | }
208 | };
209 | }
210 |
211 | namespace winrt::PhotoEditor::factory_implementation
212 | {
213 | struct Photo : PhotoT
214 | {
215 | };
216 | }
--------------------------------------------------------------------------------
/PhotoEditor/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
24 |
25 |
35 |
36 |
37 |
38 | 4
39 | 4
40 | 16
41 |
42 |
43 |
45 |
46 |
47 |
49 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
67 |
68 |
70 |
72 |
75 |
76 |
77 |
79 |
82 |
84 |
87 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
101 |
102 |
103 |
104 |
105 |
109 |
110 |
115 |
116 |
117 |
118 |
123 |
124 |
127 |
128 |
129 |
130 |
132 |
133 |
134 |
135 |
136 |
137 |
150 |
151 |
152 |
153 |
154 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/PhotoEditor/DetailPage.h:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #pragma once
26 | #include "DetailPage.g.h"
27 | #include
28 |
29 | namespace winrt::PhotoEditor::implementation
30 | {
31 | struct DetailPage : DetailPageT, std::enable_shared_from_this
32 | {
33 | DetailPage();
34 |
35 | // Retrieves Photo object.
36 | PhotoEditor::Photo Item() const
37 | {
38 | return m_item;
39 | }
40 |
41 | // Sets Photo object
42 | void Item(PhotoEditor::Photo const& value)
43 | {
44 | m_item = value;
45 | }
46 |
47 | // Resizes image to fit screen.
48 | void FitToScreen();
49 |
50 | // Resizes image to its actual size.
51 | void ShowActualSize();
52 |
53 | // Resizes image after tap.
54 | void UpdateZoomState();
55 |
56 | // Updates image brush based on set effect and its value.
57 | void UpdateEffectBrush(hstring const&);
58 |
59 | // Clears effects back to default.
60 | void ResetEffects();
61 |
62 | // Resets the color effects.
63 | void ResetColorEffects()
64 | {
65 | Item().Tint(0);
66 | Item().Temperature(0);
67 | Item().Saturation(1);
68 | }
69 |
70 | // Resets the light effects.
71 | void ResetLightEffects()
72 | {
73 | Item().Contrast(0);
74 | Item().Exposure(0);
75 | }
76 |
77 | // Resets the blur effects.
78 | void ResetBlurEffects()
79 | {
80 | Item().BlurAmount(0);
81 | }
82 |
83 | // Resets the sepia effects.
84 | void ResetSepiaEffects()
85 | {
86 | Item().Intensity(.5f);
87 | }
88 |
89 | // Event handler for navigation to DetailPage view.
90 | Windows::Foundation::IAsyncAction OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs);
91 |
92 | // Prepares animation for navigation back to MainPage view.
93 | void OnNavigatingFrom(Windows::UI::Xaml::Navigation::NavigatingCancelEventArgs const&);
94 |
95 | // Event handlers
96 | void BackButton_ItemClick(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
97 | void ZoomSlider_ValueChanged(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs const&);
98 | void MainImageScroller_ViewChanged(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs const&);
99 | void Effects_SelectionChanged(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Controls::SelectionChangedEventArgs const&);
100 | void EditButton_Check(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
101 | void EditButton_Uncheck(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
102 | void TextBlock_Tapped(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::Input::TappedRoutedEventArgs const&);
103 | void RemoveAllEffectsButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
104 | Windows::Foundation::IAsyncAction SaveButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
105 | void SelectEffectsButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
106 | void ApplyEffectsButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
107 | void CancelEffectsButton_Click(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&);
108 |
109 | private:
110 | // Initializes all image effects.
111 | void InitializeEffects();
112 |
113 | // Generate preview of effects for effect selection UI.
114 | void InitializeEffectPreviews();
115 | Windows::Foundation::IAsyncAction InitializeEffectPreview(Windows::Foundation::IInspectable, Windows::UI::Xaml::Controls::Image);
116 |
117 | // Creates the effects graph based on the selected effects.
118 | void CreateEffectsGraph();
119 |
120 | // Configure and generate resources for rendering.
121 | void UpdateMainImageBrush();
122 | void UpdatePanelState();
123 | void PrepareSelectedEffects();
124 | void ApplyEffects();
125 | void UpdateButtonImageBrush();
126 |
127 | // Backing field for Photo object.
128 | PhotoEditor::Photo m_item{ nullptr };
129 |
130 | // Indicates whether the effects controls are shown.
131 | bool m_showControls = false;
132 |
133 | event_revoker m_propertyChangedToken;
134 |
135 | // Field to store page Compositor for creation of types in the Windows.UI.Composition namespace.
136 | Windows::UI::Composition::Compositor m_compositor{ nullptr };
137 |
138 | // Fields for image effects, animation registration, and collection for effects graph.
139 | Microsoft::Graphics::Canvas::Effects::ContrastEffect m_contrastEffect{};
140 | Microsoft::Graphics::Canvas::Effects::ExposureEffect m_exposureEffect{};
141 | Microsoft::Graphics::Canvas::Effects::TemperatureAndTintEffect m_temperatureAndTintEffect{};
142 | Microsoft::Graphics::Canvas::Effects::GaussianBlurEffect m_blurEffect{};
143 | Microsoft::Graphics::Canvas::Effects::SaturationEffect m_saturationEffect{};
144 | Microsoft::Graphics::Canvas::Effects::SepiaEffect m_sepiaEffect{};
145 | Microsoft::Graphics::Canvas::Effects::GrayscaleEffect m_grayscaleEffect{};
146 | Microsoft::Graphics::Canvas::Effects::InvertEffect m_invertEffect{};
147 | Microsoft::Graphics::Canvas::Effects::CompositeEffect m_graphicsEffect{};
148 | Windows::UI::Composition::CompositionEffectBrush m_combinedBrush{ nullptr };
149 |
150 | std::vector m_selectedEffectsTemp{};
151 | std::vector m_animatablePropertiesList{};
152 |
153 | // The effects do not inherit from a common interface that contracts the Source property,
154 | // so we need to use a std::variant.
155 | std::vector> m_effectsList{};
164 |
165 | // Photo image
166 | Windows::UI::Xaml::Media::Imaging::BitmapImage m_imageSource{ nullptr };
167 |
168 | };
169 | }
170 |
171 | namespace winrt::PhotoEditor::factory_implementation
172 | {
173 | struct DetailPage : DetailPageT
174 | {
175 | };
176 | }
--------------------------------------------------------------------------------
/PhotoEditor/PhotoEditor.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | true
7 | {a7508b85-cf3d-4d77-8442-71255c16f18c}
8 | PhotoEditor
9 | PhotoEditor
10 | en-US
11 | 15.0
12 | true
13 | Windows Store
14 | 10.0
15 | 10.0.20348.0
16 | 10.0.20348.0
17 |
18 |
19 |
20 |
21 | Debug
22 | ARM
23 |
24 |
25 | Debug
26 | Win32
27 |
28 |
29 | Debug
30 | x64
31 |
32 |
33 | Release
34 | ARM
35 |
36 |
37 | Release
38 | Win32
39 |
40 |
41 | Release
42 | x64
43 |
44 |
45 |
46 | Application
47 | v142
48 | Unicode
49 |
50 |
51 | true
52 | true
53 |
54 |
55 | false
56 | true
57 | false
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Use
69 | pch.h
70 | $(IntDir)pch.pch
71 | Level4
72 | false
73 | %(AdditionalOptions) /permissive- /bigobj
74 | 4453;28204
75 | false
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | DetailPage.xaml
87 | Code
88 |
89 |
90 |
91 | App.xaml
92 |
93 |
94 | MainPage.xaml
95 |
96 |
97 | Photo.idl
98 | Code
99 |
100 |
101 |
102 |
103 | Designer
104 |
105 |
106 | Designer
107 |
108 |
109 | Designer
110 |
111 |
112 |
113 |
114 | Designer
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | DetailPage.xaml
134 | Code
135 |
136 |
137 | Create
138 |
139 |
140 | App.xaml
141 |
142 |
143 | MainPage.xaml
144 |
145 |
146 | Photo.idl
147 | Code
148 |
149 |
150 |
151 |
152 | App.xaml
153 |
154 |
155 | DetailPage.xaml
156 | Code
157 |
158 |
159 | MainPage.xaml
160 |
161 |
162 | Designer
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
173 |
174 |
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/PhotoEditor/MainPage.cpp:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #include "pch.h"
26 | #include "MainPage.h"
27 | #include "Photo.h"
28 |
29 | using namespace winrt;
30 | using namespace Windows::Foundation;
31 | using namespace Windows::Foundation::Collections;
32 | using namespace Windows::Storage;
33 | using namespace Windows::Storage::Search;
34 | using namespace Windows::Storage::Streams;
35 | using namespace Windows::UI::Composition;
36 | using namespace Windows::UI::Xaml::Navigation;
37 | using namespace Windows::UI::Xaml;
38 | using namespace Windows::UI::Xaml::Controls;
39 | using namespace Windows::UI::Xaml::Data;
40 | using namespace Windows::UI::Xaml::Hosting;
41 | using namespace Windows::UI::Xaml::Media::Animation;
42 | using namespace Windows::UI::Xaml::Media::Imaging;
43 |
44 | namespace winrt::PhotoEditor::implementation
45 | {
46 | // Page constructor.
47 | MainPage::MainPage() :
48 | m_photos(winrt::single_threaded_observable_vector()),
49 | m_compositor(Window::Current().Compositor())
50 | {
51 | InitializeComponent();
52 | ParaView().Source(ForegroundElement());
53 | }
54 |
55 | // Loads collection of Photos from users Pictures library.
56 | IAsyncAction MainPage::OnNavigatedTo(NavigationEventArgs e)
57 | {
58 | // Load photos if they haven't previously been loaded.
59 | if (Photos().Size() == 0)
60 | {
61 | m_elementImplicitAnimation = m_compositor.CreateImplicitAnimationCollection();
62 |
63 | // Define trigger and animation that should play when the trigger is triggered.
64 | m_elementImplicitAnimation.Insert(L"Offset", CreateOffsetAnimation());
65 |
66 | co_await GetItemsAsync();
67 | }
68 | }
69 |
70 | IAsyncAction MainPage::OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
71 | {
72 | auto elementVisual = ElementCompositionPreview::GetElementVisual(args.ItemContainer());
73 | auto image = args.ItemContainer().ContentTemplateRoot().as();
74 |
75 | if (args.InRecycleQueue())
76 | {
77 | elementVisual.ImplicitAnimations(nullptr);
78 |
79 | image.Source(nullptr);
80 | }
81 |
82 | if (args.Phase() == 0)
83 | {
84 | //Add implicit animation to each visual.
85 | elementVisual.ImplicitAnimations(m_elementImplicitAnimation);
86 |
87 | args.RegisterUpdateCallback([&](auto sender, auto args)
88 | {
89 | OnContainerContentChanging(sender, args);
90 | });
91 |
92 | args.Handled(true);
93 | }
94 |
95 | if (args.Phase() == 1)
96 | {
97 | // It's phase 1, so show this item's image.
98 | image.Opacity(100);
99 |
100 | auto item = unbox_value(args.Item());
101 | Photo* impleType = get_self(item);
102 |
103 | try
104 | {
105 | auto thumbnail = co_await impleType->GetImageThumbnailAsync();
106 | image.Source(thumbnail);
107 | }
108 | catch (winrt::hresult_error)
109 | {
110 | // File could be corrupt, or it might have an image file
111 | // extension, but not really be an image file.
112 | BitmapImage bitmapImage{};
113 | Uri uri{ image.BaseUri().AbsoluteUri(), L"Assets/StoreLogo.png" };
114 | bitmapImage.UriSource(uri);
115 | image.Source(bitmapImage);
116 | }
117 | }
118 | }
119 |
120 | // Called by the Loaded event of the ImageGridView for animation after back navigation from DetailPage view.
121 | IAsyncAction MainPage::StartConnectedAnimationForBackNavigation()
122 | {
123 | // Run the connected animation for navigation back to the main page from the detail page.
124 | if (m_persistedItem)
125 | {
126 | ImageGridView().ScrollIntoView(m_persistedItem);
127 | auto animation = ConnectedAnimationService::GetForCurrentView().GetAnimation(L"backAnimation");
128 | if (animation)
129 | {
130 | co_await ImageGridView().TryStartConnectedAnimationAsync(animation, m_persistedItem, L"ItemImage");
131 | }
132 | }
133 | }
134 |
135 | // Registers property changed event handler.
136 | event_token MainPage::PropertyChanged(PropertyChangedEventHandler const& value)
137 | {
138 | return m_propertyChanged.add(value);
139 | }
140 |
141 | // Unregisters property changed event handler.
142 | void MainPage::PropertyChanged(event_token const& token)
143 | {
144 | m_propertyChanged.remove(token);
145 | }
146 |
147 | // Loads images from the user's Pictures library.
148 | IAsyncAction MainPage::GetItemsAsync()
149 | {
150 | // Show the loading progress bar.
151 | LoadProgressIndicator().Visibility(Windows::UI::Xaml::Visibility::Visible);
152 | NoPicsText().Visibility(Windows::UI::Xaml::Visibility::Collapsed);
153 |
154 | // File type filter.
155 | QueryOptions options{};
156 | options.FolderDepth(FolderDepth::Deep);
157 | options.FileTypeFilter().Append(L".jpg");
158 | options.FileTypeFilter().Append(L".png");
159 | options.FileTypeFilter().Append(L".gif");
160 |
161 | // Get the Pictures library.
162 | StorageFolder picturesFolder = KnownFolders::PicturesLibrary();
163 | auto result = picturesFolder.CreateFileQueryWithOptions(options);
164 | auto imageFiles = co_await result.GetFilesAsync();
165 | auto unsupportedFilesFound = false;
166 |
167 | // Populate Photos collection.
168 | for (auto&& file : imageFiles)
169 | {
170 | // Only files on the local computer are supported.
171 | // Files on OneDrive or a network location are excluded.
172 | if (file.Provider().Id() == L"computer")
173 | {
174 | auto image = co_await LoadImageInfoAsync(file);
175 | Photos().Append(image);
176 | }
177 | else
178 | {
179 | unsupportedFilesFound = true;
180 | }
181 | }
182 |
183 | if (Photos().Size() == 0)
184 | {
185 | // No pictures were found in the library, so show message.
186 | NoPicsText().Visibility(Windows::UI::Xaml::Visibility::Visible);
187 | }
188 |
189 | // Hide the loading progress bar.
190 | LoadProgressIndicator().Visibility(Windows::UI::Xaml::Visibility::Collapsed);
191 |
192 | if (unsupportedFilesFound)
193 | {
194 | ContentDialog unsupportedFilesDialog{};
195 | unsupportedFilesDialog.Title(box_value(L"Unsupported images found"));
196 | unsupportedFilesDialog.Content(box_value(L"This sample app only supports images stored locally on the computer. We found files in your library that are stored in OneDrive or another network location. We didn't load those images."));
197 | unsupportedFilesDialog.CloseButtonText(L"Ok");
198 |
199 | co_await unsupportedFilesDialog.ShowAsync();
200 | }
201 | }
202 |
203 | // Creates a Photo from Storage file for adding to Photo collection.
204 | IAsyncOperation MainPage::LoadImageInfoAsync(StorageFile file)
205 | {
206 | auto properties = co_await file.Properties().GetImagePropertiesAsync();
207 | auto info = winrt::make(properties, file, file.DisplayName(), file.DisplayType());
208 | co_return info;
209 | }
210 |
211 | CompositionAnimationGroup MainPage::CreateOffsetAnimation()
212 | {
213 | //Define Offset Animation for the Animation group.
214 | Vector3KeyFrameAnimation offsetAnimation = m_compositor.CreateVector3KeyFrameAnimation();
215 | offsetAnimation.InsertExpressionKeyFrame(1.0f, L"this.FinalValue");
216 | TimeSpan span{ std::chrono::milliseconds{400} };
217 | offsetAnimation.Duration(span);
218 |
219 | //Define Animation Target for this animation to animate using definition.
220 | offsetAnimation.Target(L"Offset");
221 |
222 | //Add Animations to Animation group.
223 | CompositionAnimationGroup animationGroup = m_compositor.CreateAnimationGroup();
224 | animationGroup.Add(offsetAnimation);
225 |
226 | return animationGroup;
227 | }
228 |
229 | // Photo clicked event handler for navigation to DetailPage view.
230 | void MainPage::ImageGridView_ItemClick(IInspectable const sender, ItemClickEventArgs const e)
231 | {
232 | // Prepare the connected animation for navigation to the detail page.
233 | m_persistedItem = e.ClickedItem().as();
234 | ImageGridView().PrepareConnectedAnimation(L"itemAnimation", e.ClickedItem(), L"ItemImage");
235 |
236 | auto m_suppress = SuppressNavigationTransitionInfo();
237 | Frame().Navigate(xaml_typename(), e.ClickedItem(), m_suppress);
238 | }
239 |
240 | // Triggers property changed notification.
241 | void MainPage::RaisePropertyChanged(hstring const& propertyName)
242 | {
243 | m_propertyChanged(*this, PropertyChangedEventArgs(propertyName));
244 | }
245 | }
--------------------------------------------------------------------------------
/PhotoEditor/DetailPage.cpp:
--------------------------------------------------------------------------------
1 | // ---------------------------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | // The MIT License (MIT)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE
23 | // ---------------------------------------------------------------------------------
24 |
25 | #include "pch.h"
26 | #include "DetailPage.h"
27 | #include "Photo.h"
28 |
29 | using namespace winrt;
30 | using namespace Microsoft::Graphics::Canvas;
31 | using namespace Microsoft::Graphics::Canvas::Effects;
32 | using namespace Microsoft::Graphics::Canvas::Text;
33 | using namespace Microsoft::Graphics::Canvas::UI::Xaml;
34 | using namespace Microsoft::Graphics::Canvas::UI;
35 | using namespace Windows::Foundation;
36 | using namespace Windows::Foundation::Numerics;
37 | using namespace Windows::Graphics::Effects;
38 | using namespace Windows::Graphics::Imaging;
39 | using namespace Windows::Storage;
40 | using namespace Windows::Storage::Search;
41 | using namespace Windows::Storage::Streams;
42 | using namespace Windows::Storage::Pickers;
43 | using namespace Windows::UI;
44 | using namespace Windows::UI::Composition;
45 | using namespace Windows::UI::Xaml;
46 | using namespace Windows::UI::Xaml::Controls;
47 | using namespace Windows::UI::Xaml::Hosting;
48 | using namespace Windows::UI::Xaml::Input;
49 | using namespace Windows::UI::Xaml::Media::Imaging;
50 | using namespace Windows::UI::Xaml::Media::Animation;
51 | using namespace Windows::UI::Xaml::Navigation;
52 |
53 | namespace winrt::PhotoEditor::implementation
54 | {
55 | DetailPage::DetailPage() : m_compositor(Window::Current().Compositor())
56 | {
57 | InitializeComponent();
58 | EditButton().IsChecked(true);
59 | }
60 |
61 | // Calculates and resizes image based on screen size
62 | void DetailPage::FitToScreen()
63 | {
64 | auto a = MainImageScroller().ActualWidth() / Item().ImageProperties().Width();
65 | auto b = MainImageScroller().ActualHeight() / Item().ImageProperties().Height();
66 | auto ZoomFactor = static_cast(std::min(a, b));
67 | MainImageScroller().ChangeView(nullptr, nullptr, ZoomFactor);
68 | }
69 |
70 | // Resizes image to full size
71 | void DetailPage::ShowActualSize()
72 | {
73 | MainImageScroller().ChangeView(nullptr, nullptr, 1);
74 | }
75 |
76 | // Changes image size after Tap, toggling between FitToScreen and ShowActualSize
77 | void DetailPage::UpdateZoomState()
78 | {
79 | if (MainImageScroller().ZoomFactor() == 1)
80 | {
81 | FitToScreen();
82 | }
83 | else
84 | {
85 | ShowActualSize();
86 | }
87 | }
88 |
89 | void DetailPage::SelectEffectsButton_Click(IInspectable const&, RoutedEventArgs const&)
90 | {
91 | // Show effects previews, hide controls.
92 | VisualStateManager().GoToState(*this, L"ChooseEffects", true);
93 |
94 | // Save selected effects so they can be restored if this op is canceled.
95 | m_selectedEffectsTemp.clear();
96 | for (auto&& effectItem : EffectPreviewGrid().SelectedItems())
97 | {
98 | m_selectedEffectsTemp.push_back(effectItem);
99 | }
100 | }
101 |
102 | void DetailPage::UpdatePanelState()
103 | {
104 | if (m_showControls)
105 | {
106 | VisualStateManager().GoToState(*this, L"EditEffects", true);
107 | }
108 | else if (EffectPreviewGrid().SelectedItems().Size() == 0)
109 | {
110 | // No effects are selected.
111 | VisualStateManager().GoToState(*this, L"Normal", true);
112 | }
113 | else
114 | {
115 | // Only effects with no additional controls are selected.
116 | VisualStateManager().GoToState(*this, L"SaveEffects", true);
117 | }
118 | }
119 |
120 | void DetailPage::PrepareSelectedEffects()
121 | {
122 | m_effectsList.clear();
123 | m_animatablePropertiesList.clear();
124 |
125 | sepiaControlsGrid().Visibility(Visibility::Collapsed);
126 | blurControlsGrid().Visibility(Visibility::Collapsed);
127 | colorControlsGrid().Visibility(Visibility::Collapsed);
128 | lightControlsGrid().Visibility(Visibility::Collapsed);
129 |
130 | m_showControls = false;
131 | GridView epg = EffectPreviewGrid().as();
132 |
133 | // Add effects.
134 | for (auto&& item : epg.SelectedItems())
135 | {
136 | auto preview = item.as();
137 | auto tag = unbox_value(preview.Tag());
138 |
139 | if (tag == L"sepia")
140 | {
141 | // This intensity is applied only to the button preview.
142 | m_sepiaEffect.Intensity(1.0f);
143 | m_effectsList.push_back(m_sepiaEffect);
144 | m_animatablePropertiesList.push_back(L"SepiaEffect.Intensity");
145 | sepiaControlsGrid().Visibility(Visibility::Visible);
146 | m_showControls = true;
147 | }
148 | else if (tag == L"invert")
149 | {
150 | m_effectsList.push_back(m_invertEffect);
151 | }
152 | else if (tag == L"grayscale")
153 | {
154 | m_effectsList.push_back(m_grayscaleEffect);
155 | }
156 | else if (tag == L"blur")
157 | {
158 | // This blur amount is applied only to the button preview.
159 | m_blurEffect.BlurAmount(2.5f);
160 | m_effectsList.push_back(m_blurEffect);
161 | m_animatablePropertiesList.push_back(L"BlurEffect.BlurAmount");
162 | blurControlsGrid().Visibility(Visibility::Visible);
163 | m_showControls = true;
164 | }
165 | else if (tag == L"color")
166 | {
167 | // These values are applied only to the button preview.
168 | m_temperatureAndTintEffect.Temperature(0.25f);
169 | m_temperatureAndTintEffect.Tint(-0.25f);
170 | m_effectsList.push_back(m_temperatureAndTintEffect);
171 | m_animatablePropertiesList.push_back(L"TemperatureAndTintEffect.Temperature");
172 | m_animatablePropertiesList.push_back(L"TemperatureAndTintEffect.Tint");
173 | m_effectsList.push_back(m_saturationEffect);
174 | m_animatablePropertiesList.push_back(L"SaturationEffect.Saturation");
175 | colorControlsGrid().Visibility(Visibility::Visible);
176 | m_showControls = true;
177 | }
178 | else if (tag == L"light")
179 | {
180 | // This contrast amount is applied only to the button preview.
181 | m_contrastEffect.Contrast(.25f);
182 | m_effectsList.push_back(m_contrastEffect);
183 | m_animatablePropertiesList.push_back(L"ContrastEffect.Contrast");
184 | // This exposure amount is applied only to the button preview.
185 | m_exposureEffect.Exposure(-0.25f);
186 | m_effectsList.push_back(m_exposureEffect);
187 | m_animatablePropertiesList.push_back(L"ExposureEffect.Exposure");
188 | lightControlsGrid().Visibility(Visibility::Visible);
189 | m_showControls = true;
190 | }
191 | }
192 |
193 | m_effectsList.push_back(m_graphicsEffect);
194 | }
195 |
196 | void DetailPage::ApplyEffects()
197 | {
198 | PrepareSelectedEffects();
199 | UpdateMainImageBrush();
200 |
201 | for (auto&& item : m_animatablePropertiesList)
202 | {
203 | std::wstring str = static_cast(item);
204 | auto index = str.find_last_of(L'.', str.size());
205 | hstring prop = static_cast(str.substr(index + 1, str.size()));
206 | UpdateEffectBrush(prop);
207 | }
208 | }
209 |
210 | void DetailPage::ApplyEffectsButton_Click(IInspectable const&, RoutedEventArgs const&)
211 | {
212 | UpdatePanelState();
213 | ApplyEffects();
214 | }
215 |
216 | void DetailPage::CancelEffectsButton_Click(IInspectable const&, RoutedEventArgs const&)
217 | {
218 | UpdatePanelState();
219 | EffectPreviewGrid().SelectedItems().Clear();
220 | for (auto&& effectItem : m_selectedEffectsTemp)
221 | {
222 | EffectPreviewGrid().SelectedItems().Append(effectItem);
223 | }
224 | }
225 |
226 | void DetailPage::UpdateButtonImageBrush()
227 | {
228 | ButtonPreviewImage().Source(m_imageSource);
229 | ButtonPreviewImage().InvalidateArrange();
230 |
231 | CreateEffectsGraph();
232 |
233 | auto destinationBrush = m_compositor.CreateBackdropBrush();
234 | auto graphicsEffectFactory = m_compositor.CreateEffectFactory(m_graphicsEffect);
235 |
236 | auto previewBrush = graphicsEffectFactory.CreateBrush();
237 | previewBrush.SetSourceParameter(L"Backdrop", destinationBrush);
238 |
239 | auto effectSprite = m_compositor.CreateSpriteVisual();
240 | effectSprite.Size(float2{ 232, 64 });
241 | effectSprite.Brush(previewBrush);
242 | ElementCompositionPreview::SetElementChildVisual(ButtonPreviewImage(), effectSprite);
243 | }
244 |
245 |
246 | // Adds or updates specific effect value within combined brush.
247 | void DetailPage::UpdateEffectBrush(hstring const& propertyName)
248 | {
249 | if (m_combinedBrush)
250 | {
251 | if (propertyName == L"Exposure")
252 | {
253 | m_combinedBrush.Properties().InsertScalar(L"ExposureEffect.Exposure", Item().Exposure());
254 | }
255 | else if (propertyName == L"Temperature")
256 | {
257 | m_combinedBrush.Properties().InsertScalar(L"TemperatureAndTintEffect.Temperature", Item().Temperature());
258 | }
259 | else if (propertyName == L"Tint")
260 | {
261 | m_combinedBrush.Properties().InsertScalar(L"TemperatureAndTintEffect.Tint", Item().Tint());
262 | }
263 | else if (propertyName == L"Contrast")
264 | {
265 | m_combinedBrush.Properties().InsertScalar(L"ContrastEffect.Contrast", Item().Contrast());
266 | }
267 | else if (propertyName == L"Saturation")
268 | {
269 | m_combinedBrush.Properties().InsertScalar(L"SaturationEffect.Saturation", Item().Saturation());
270 | }
271 | else if (propertyName == L"BlurAmount")
272 | {
273 | m_combinedBrush.Properties().InsertScalar(L"BlurEffect.BlurAmount", Item().BlurAmount());
274 | }
275 | else if (propertyName == L"Intensity")
276 | {
277 | m_combinedBrush.Properties().InsertScalar(L"SepiaEffect.Intensity", Item().Intensity());
278 | }
279 | }
280 | }
281 |
282 | // Resets effects to their default values.
283 | void DetailPage::ResetEffects()
284 | {
285 | Item().Exposure(0);
286 | Item().BlurAmount(0);
287 | Item().Tint(0);
288 | Item().Temperature(0);
289 | Item().Contrast(0);
290 | Item().Saturation(1);
291 | Item().Intensity(0.5F);
292 | }
293 |
294 | // Retrieves appropriate photo, sets up detail view, and performs animation.
295 | IAsyncAction DetailPage::OnNavigatedTo(NavigationEventArgs e)
296 | {
297 | Item(e.Parameter().as());
298 |
299 | if (auto item = Item())
300 | {
301 | Photo* impleType = get_self(item);
302 | m_imageSource = co_await impleType->GetImageSourceAsync();
303 |
304 | // Because DetailPage can be destroyed during the life of the event handler,
305 | // it is good practice to create a weak_ref to *this, capture it in the lambda, and resolve it before use.
306 | m_propertyChangedToken = item.PropertyChanged(auto_revoke, [weak{ get_weak() }](auto&&, auto&& args)
307 | {
308 | if (auto strong = weak.get())
309 | {
310 | strong->UpdateEffectBrush(args.PropertyName());
311 | }
312 | });
313 |
314 | targetImage().Source(m_imageSource);
315 |
316 | ConnectedAnimation imageAnimation = ConnectedAnimationService::GetForCurrentView().GetAnimation(L"itemAnimation");
317 | if (imageAnimation)
318 | {
319 | imageAnimation.Completed([weak{ get_weak() }](auto&&, auto&&)
320 | {
321 | if (auto strong = weak.get())
322 | {
323 | strong->MainImage().Source(strong->m_imageSource);
324 | strong->MainImage().Visibility(Visibility::Visible);
325 | strong->targetImage().Source(nullptr);
326 |
327 | strong->InitializeEffects();
328 | strong->UpdateMainImageBrush();
329 | strong->InitializeEffectPreviews();
330 | strong->UpdateButtonImageBrush();
331 | }
332 | });
333 |
334 | imageAnimation.TryStart(targetImage());
335 | }
336 | if (m_imageSource.PixelHeight() == 0 && m_imageSource.PixelWidth() == 0)
337 | {
338 | // There is no editable image loaded. Disable zoom and edit
339 | // to prevent other errors.
340 | EditButton().IsEnabled(false);
341 | ZoomButton().IsEnabled(false);
342 | }
343 | }
344 |
345 | BackButton().IsEnabled(Frame().CanGoBack());
346 | }
347 |
348 | // Prepares animation for navigation back to MainPage view.
349 | void DetailPage::OnNavigatingFrom(NavigatingCancelEventArgs const& e)
350 | {
351 | if (e.NavigationMode() == NavigationMode::Back)
352 | {
353 | ResetEffects();
354 | ConnectedAnimationService::GetForCurrentView().PrepareToAnimate(L"backAnimation", MainImage());
355 | }
356 | }
357 |
358 | // Initializes image effects prior to creation of effect graph.
359 | void DetailPage::InitializeEffects()
360 | {
361 | m_saturationEffect.Name(L"SaturationEffect");
362 | m_saturationEffect.Saturation(Item().Saturation());
363 | m_sepiaEffect.Name(L"SepiaEffect");
364 | m_sepiaEffect.Intensity(Item().Intensity());
365 | m_invertEffect.Source(CompositionEffectSourceParameter{ L"source" });
366 | m_grayscaleEffect.Source(CompositionEffectSourceParameter{ L"source" });
367 | m_contrastEffect.Name(L"ContrastEffect");
368 | m_contrastEffect.Contrast(Item().Contrast());
369 | m_exposureEffect.Name(L"ExposureEffect");
370 | m_exposureEffect.Exposure(Item().Exposure());
371 | m_temperatureAndTintEffect.Name(L"TemperatureAndTintEffect");
372 | m_temperatureAndTintEffect.Temperature(Item().Temperature());
373 | m_blurEffect.Name(L"BlurEffect");
374 | m_blurEffect.BlurAmount(Item().BlurAmount());
375 | m_blurEffect.BorderMode(EffectBorderMode::Hard);
376 | m_graphicsEffect.Sources().Append(CompositionEffectSourceParameter{ L"Backdrop" });
377 | m_effectsList.push_back(m_graphicsEffect);
378 | }
379 |
380 | // Creates all the thumbnail previews for effect selection UI.
381 | void DetailPage::InitializeEffectPreviews()
382 | {
383 | SepiaEffect sepiaEffect{};
384 | sepiaEffect.Intensity(0.5f);
385 | sepiaEffect.Source(CompositionEffectSourceParameter{ L"source" });
386 | InitializeEffectPreview(sepiaEffect, sepiaImage());
387 |
388 | GrayscaleEffect grayscaleEffect{};
389 | grayscaleEffect.Source(CompositionEffectSourceParameter{ L"source" });
390 | InitializeEffectPreview(grayscaleEffect, grayscaleImage());
391 |
392 | GaussianBlurEffect blurEffect{};
393 | blurEffect.BlurAmount(3.0f);
394 | blurEffect.Source(CompositionEffectSourceParameter{ L"source" });
395 | InitializeEffectPreview(blurEffect, blurImage());
396 |
397 | InvertEffect invertEffect{};
398 | invertEffect.Source(CompositionEffectSourceParameter{ L"source" });
399 | InitializeEffectPreview(invertEffect, invertImage());
400 |
401 | ExposureEffect lightEffect{};
402 | lightEffect.Exposure(1.0f);
403 | lightEffect.Source(CompositionEffectSourceParameter{ L"source" });
404 | InitializeEffectPreview(lightEffect, lightImage());
405 |
406 | SaturationEffect colorEffect{};
407 | colorEffect.Saturation(0.5f);
408 | colorEffect.Source(CompositionEffectSourceParameter{ L"source" });
409 | InitializeEffectPreview(colorEffect, colorImage());
410 | }
411 |
412 | // Creates a specified effect thumbnail for the effect preview UI.
413 | IAsyncAction DetailPage::InitializeEffectPreview(IInspectable compEffect, Image image)
414 | {
415 | Photo* implType = get_self(Item());
416 | image.Source(co_await implType->GetImageThumbnailAsync());
417 | image.InvalidateArrange();
418 |
419 | auto destinationBrush = m_compositor.CreateBackdropBrush();
420 | auto graphicsEffectFactory = m_compositor.CreateEffectFactory(compEffect.as());
421 | auto combinedBrush = graphicsEffectFactory.CreateBrush();
422 | auto effectSprite = m_compositor.CreateSpriteVisual();
423 |
424 | combinedBrush.SetSourceParameter(L"source", destinationBrush);
425 | effectSprite.Size(float2{ 188,88 });
426 | effectSprite.Brush(combinedBrush);
427 | ElementCompositionPreview::SetElementChildVisual(image, effectSprite);
428 | }
429 |
430 | // Creates the effects graph based on the selected effects.
431 | void DetailPage::CreateEffectsGraph()
432 | {
433 | auto as_source = [](auto&& arg) -> IGraphicsEffectSource
434 | {
435 | return arg;
436 | };
437 |
438 | // Create effects chain from list of effects.
439 | // The CompositeEffect is always the end of the chain and gets some special handling.
440 | for (size_t i = 0; i < m_effectsList.size(); i++)
441 | {
442 | const auto& effect = m_effectsList[i];
443 |
444 | if (i == 0)
445 | {
446 | std::visit([&graphicsEffect = m_graphicsEffect](auto&& effect)
447 | {
448 | CompositionEffectSourceParameter source{ L"Backdrop" };
449 | if constexpr (std::is_same_v>)
450 | {
451 | auto const& sources = graphicsEffect.Sources();
452 | sources.Clear();
453 | sources.Append(source);
454 | }
455 | else
456 | {
457 | effect.Source(source);
458 | }
459 | }, effect);
460 | }
461 | else if (i < m_effectsList.size() - 1)
462 | {
463 | std::visit([source = std::visit(as_source, m_effectsList[i - 1])](auto&& effect)
464 | {
465 | if constexpr (!std::is_same_v>)
466 | {
467 | effect.Source(source);
468 | }
469 | }, effect);
470 | }
471 | else
472 | {
473 | // CompositeEffect is the last effect in the chain.
474 | auto const& sources = m_graphicsEffect.Sources();
475 | sources.Clear();
476 | sources.Append(std::visit(as_source, m_effectsList[i - 1]));
477 | }
478 | }
479 | }
480 |
481 | void DetailPage::UpdateMainImageBrush()
482 | {
483 | MainImage().Source(m_imageSource);
484 | MainImage().InvalidateArrange();
485 |
486 | CreateEffectsGraph();
487 |
488 | auto destinationBrush = m_compositor.CreateBackdropBrush();
489 | auto graphicsEffectFactory = m_compositor.CreateEffectFactory(m_graphicsEffect, m_animatablePropertiesList);
490 |
491 | m_combinedBrush = graphicsEffectFactory.CreateBrush();
492 | m_combinedBrush.SetSourceParameter(L"Backdrop", destinationBrush);
493 |
494 | auto effectSprite = m_compositor.CreateSpriteVisual();
495 | effectSprite.Size(float2{ static_cast(m_imageSource.PixelWidth()), static_cast(m_imageSource.PixelHeight()) });
496 | effectSprite.Brush(m_combinedBrush);
497 | ElementCompositionPreview::SetElementChildVisual(MainImage(), effectSprite);
498 | }
499 |
500 | // Back button event handler for navigation back to MainPage.
501 | void DetailPage::BackButton_ItemClick(IInspectable const&, RoutedEventArgs const&)
502 | {
503 | auto m_suppress = SuppressNavigationTransitionInfo();
504 | if (Frame().CanGoBack())
505 | {
506 | Frame().GoBack(m_suppress);
507 | }
508 | }
509 |
510 | // Edit button event handler for opening edit UI.
511 | void DetailPage::EditButton_Check(IInspectable const&, RoutedEventArgs const&)
512 | {
513 | EditPanel().Visibility(Visibility::Visible);
514 | }
515 |
516 | // Edit button event handler for closing edit UI.
517 | void DetailPage::EditButton_Uncheck(IInspectable const&, RoutedEventArgs const&)
518 | {
519 | EditPanel().Visibility(Visibility::Collapsed);
520 | }
521 |
522 | void DetailPage::Effects_SelectionChanged(IInspectable const&, SelectionChangedEventArgs const&)
523 | {
524 | PrepareSelectedEffects();
525 | UpdateButtonImageBrush();
526 | }
527 |
528 | // Event handler for zoom level change.
529 | void DetailPage::ZoomSlider_ValueChanged(IInspectable const&, Primitives::RangeBaseValueChangedEventArgs const& e)
530 | {
531 | if (MainImageScroller())
532 | {
533 | MainImageScroller().ChangeView(nullptr, nullptr, static_cast(e.NewValue()));
534 | }
535 | }
536 |
537 | // Event handler for zoom level change.
538 | void DetailPage::MainImageScroller_ViewChanged(IInspectable const& sender, ScrollViewerViewChangedEventArgs const&)
539 | {
540 | ZoomSlider().Value(sender.as().ZoomFactor());
541 | }
542 |
543 | void DetailPage::TextBlock_Tapped(IInspectable const& sender, TappedRoutedEventArgs const&)
544 | {
545 | bool wasFound = false;
546 | uint32_t indexOf = 0;
547 |
548 | for (auto&& effectItem : EffectPreviewGrid().SelectedItems())
549 | {
550 | auto effectTag = unbox_value(effectItem.as().Tag());
551 |
552 | if (effectTag == unbox_value(sender.as().Tag()))
553 | {
554 | wasFound = EffectPreviewGrid().SelectedItems().IndexOf(effectItem, indexOf);
555 |
556 | if (effectTag == L"color")
557 | {
558 | ResetColorEffects();
559 | }
560 | else if (effectTag == L"light")
561 | {
562 | ResetLightEffects();
563 | }
564 | else if (effectTag == L"blur")
565 | {
566 | ResetBlurEffects();
567 | }
568 | else if (effectTag == L"sepia")
569 | {
570 | ResetSepiaEffects();
571 | }
572 | }
573 | }
574 |
575 | if (wasFound)
576 | {
577 | EffectPreviewGrid().SelectedItems().RemoveAt(indexOf);
578 | }
579 |
580 | ApplyEffects();
581 | UpdatePanelState();
582 | UpdateButtonImageBrush();
583 | }
584 |
585 | void DetailPage::RemoveAllEffectsButton_Click(IInspectable const&, RoutedEventArgs const&)
586 | {
587 | EffectPreviewGrid().SelectedItems().Clear();
588 | ResetEffects();
589 | ApplyEffects();
590 | UpdatePanelState();
591 | UpdateButtonImageBrush();
592 | }
593 |
594 | IAsyncAction DetailPage::SaveButton_Click(IInspectable const&, RoutedEventArgs const&)
595 | {
596 | // Setup the picker.
597 | auto picker = FileSavePicker{};
598 | picker.SuggestedStartLocation(PickerLocationId::PicturesLibrary);
599 | picker.SuggestedFileName(L"New Image");
600 | picker.FileTypeChoices().Insert(L"Images", winrt::single_threaded_vector({ L".jpg" }));
601 |
602 | if (auto file = co_await picker.PickSaveFileAsync())
603 | {
604 | if (auto stream = co_await file.OpenAsync(Windows::Storage::FileAccessMode::ReadWrite))
605 | {
606 | // Create the encoder from the stream.
607 | auto encoder = co_await BitmapEncoder::CreateAsync(BitmapEncoder::JpegEncoderId(), stream);
608 |
609 | RenderTargetBitmap renderTargetBitmap{};
610 | co_await renderTargetBitmap.RenderAsync(MainImage());
611 |
612 | IBuffer pixels = co_await renderTargetBitmap.GetPixelsAsync();
613 | auto newBuffer = SoftwareBitmap::CreateCopyFromBuffer
614 | (pixels, BitmapPixelFormat::Bgra8, Item().ImageProperties().Width(), Item().ImageProperties().Height());
615 |
616 | encoder.SetSoftwareBitmap(newBuffer);
617 | co_await encoder.FlushAsync();
618 |
619 | co_await Windows::Storage::CachedFileManager::CompleteUpdatesAsync(file);
620 | }
621 | }
622 | }
623 | }
--------------------------------------------------------------------------------
/PhotoEditor/DetailPage.xaml:
--------------------------------------------------------------------------------
1 |
24 |
25 |
34 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
54 |
56 |
58 |
59 |
60 |
61 |
63 |
64 |
65 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
94 |
96 |
97 |
99 |
101 |
102 |
104 |
106 |
107 |
109 |
111 |
112 |
114 |
116 |
117 |
119 |
121 |
122 |
123 |
124 |
125 |
126 |
128 |
130 |
131 |
133 |
135 |
136 |
138 |
140 |
141 |
143 |
145 |
146 |
148 |
150 |
151 |
153 |
155 |
156 |
158 |
160 |
161 |
163 |
165 |
166 |
168 |
170 |
171 |
173 |
175 |
176 |
178 |
180 |
181 |
183 |
185 |
186 |
187 |
188 |
189 |
190 |
192 |
194 |
195 |
197 |
199 |
200 |
202 |
204 |
205 |
207 |
209 |
210 |
212 |
214 |
215 |
217 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
229 |
231 |
232 |
234 |
236 |
237 |
238 |
239 |
240 |
241 |
243 |
245 |
246 |
248 |
250 |
251 |
252 |
253 |
254 |
255 |
264 |
268 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
285 |
288 |
295 |
301 |
309 |
319 |
320 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
338 |
342 |
349 |
355 |
363 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
385 |
390 |
391 |
397 |
401 |
405 |
406 |
407 |
411 |
413 |
420 |
423 |
424 |
425 |
429 |
430 |
431 |
432 |
433 |
434 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
452 |
453 |
459 |
465 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
521 |
522 |
534 |
543 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
581 |
582 |
586 |
590 |
591 |
592 |
599 |
600 |
602 |
603 |
605 |
607 |
608 |
609 |
610 |
611 |
612 |
619 |
620 |
622 |
623 |
625 |
627 |
628 |
629 |
630 |
631 |
632 |
637 |
638 |
639 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
654 |
655 |
659 |
663 |
664 |
665 |
672 |
673 |
675 |
676 |
678 |
680 |
681 |
682 |
683 |
684 |
685 |
691 |
692 |
693 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
707 |
708 |
712 |
716 |
717 |
718 |
723 |
724 |
725 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
739 |
740 |
744 |
748 |
749 |
750 |
755 |
756 |
757 |
758 |
759 |
761 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
775 |
777 |
778 |
779 |
780 |
781 |
783 |
785 |
787 |
789 |
790 |
791 |
792 |
793 |
795 |
797 |
799 |
801 |
802 |
803 |
804 |
805 |
806 |
--------------------------------------------------------------------------------