├── .gitignore
├── LICENSE
├── MobileApp
├── ExpenseIt
│ ├── ExpenseIt.Droid
│ │ ├── Assets
│ │ │ └── AboutAssets.txt
│ │ ├── InvoiceIt.Droid.csproj
│ │ ├── MainActivity.cs
│ │ ├── MainApplication.cs
│ │ ├── Properties
│ │ │ ├── AndroidManifest.xml
│ │ │ └── AssemblyInfo.cs
│ │ ├── Resources
│ │ │ ├── AboutResources.txt
│ │ │ ├── Resource.Designer.cs
│ │ │ ├── drawable-hdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable
│ │ │ │ └── icon.png
│ │ │ ├── layout
│ │ │ │ ├── Tabbar.axml
│ │ │ │ └── Toolbar.axml
│ │ │ └── values
│ │ │ │ └── styles.xml
│ │ ├── app.config
│ │ └── packages.config
│ ├── ExpenseIt.UWP
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── Assets
│ │ │ ├── LockScreenLogo.scale-200.png
│ │ │ ├── SplashScreen.scale-200.png
│ │ │ ├── Square150x150Logo.scale-200.png
│ │ │ ├── Square44x44Logo.scale-200.png
│ │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ │ ├── StoreLogo.png
│ │ │ └── Wide310x150Logo.scale-200.png
│ │ ├── InvoiceIt.UWP.csproj
│ │ ├── InvoiceIt.UWP.nuget.targets
│ │ ├── MainPage.xaml
│ │ ├── MainPage.xaml.cs
│ │ ├── Package.appxmanifest
│ │ ├── Properties
│ │ │ ├── AssemblyInfo.cs
│ │ │ └── Default.rd.xml
│ │ ├── project.json
│ │ └── project.lock.json
│ ├── ExpenseIt.iOS
│ │ ├── AppDelegate.cs
│ │ ├── Entitlements.plist
│ │ ├── Info.plist
│ │ ├── InvoiceIt.iOS.csproj
│ │ ├── Main.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── Resources
│ │ │ ├── Default-568h@2x.png
│ │ │ ├── Default-Portrait.png
│ │ │ ├── Default-Portrait@2x.png
│ │ │ ├── Default.png
│ │ │ ├── Default@2x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small-40.png
│ │ │ ├── Icon-Small-40@2x.png
│ │ │ ├── Icon-Small-40@3x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ └── LaunchScreen.storyboard
│ │ ├── app.config
│ │ ├── iTunesArtwork
│ │ ├── iTunesArtwork@2x
│ │ └── packages.config
│ └── ExpenseIt
│ │ ├── APIResponse.cs
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── CardViewCell.cs
│ │ ├── Expense.cs
│ │ ├── InvoiceIt.csproj
│ │ ├── InvoicesPage.xaml
│ │ ├── InvoicesPage.xaml.cs
│ │ ├── InvoicesViewModel.cs
│ │ ├── MLResponseOutput.cs
│ │ ├── Properties
│ │ └── AssemblyInfo.cs
│ │ ├── app.config
│ │ └── packages.config
└── InvoiceIt.sln
├── README.md
├── ocr-from-url.py
├── ocr.py
├── prep-data.py
├── prep-image-url.py
└── redistribute-data.py
/.gitignore:
--------------------------------------------------------------------------------
1 | #credential
2 | config.ini
3 |
4 | # Byte-compiled / optimized / DLL files
5 | __pycache__/
6 | *.py[cod]
7 | *$py.class
8 |
9 | # C extensions
10 | *.so
11 |
12 | # Distribution / packaging
13 | .Python
14 | env/
15 | build/
16 | develop-eggs/
17 | dist/
18 | downloads/
19 | eggs/
20 | .eggs/
21 | lib/
22 | lib64/
23 | parts/
24 | sdist/
25 | var/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *,cover
49 | .hypothesis/
50 |
51 | # Translations
52 | *.mo
53 | *.pot
54 |
55 | # Django stuff:
56 | *.log
57 | local_settings.py
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # IPython Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # dotenv
82 | .env
83 |
84 | # virtualenv
85 | venv/
86 | ENV/
87 |
88 | # Spyder project settings
89 | .spyderproject
90 | .spyderworkspace
91 |
92 | # Rope project settings
93 | .ropeproject
94 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Microsoft Partner Catalyst Team
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.
22 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with you package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
20 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/InvoiceIt.Droid.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}
9 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | Library
11 | Properties
12 | InvoiceIt.Droid
13 | InvoiceIt.Droid
14 | 512
15 | true
16 | Resources\Resource.Designer.cs
17 | Off
18 | Properties\AndroidManifest.xml
19 | true
20 | v6.0
21 | armeabi,armeabi-v7a,x86
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | true
31 | full
32 | false
33 | bin\Debug\
34 | DEBUG;TRACE
35 | prompt
36 | 4
37 | True
38 | None
39 |
40 |
41 | pdbonly
42 | true
43 | bin\Release\
44 | TRACE
45 | prompt
46 | 4
47 | False
48 | SdkOnly
49 |
50 |
51 |
52 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\MonoAndroid10\FormsViewGroup.dll
53 | True
54 |
55 |
56 |
57 |
58 | ..\..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll
59 | True
60 |
61 |
62 | ..\..\packages\Xam.Plugin.Media.2.3.0\lib\MonoAndroid10\Plugin.Media.dll
63 | True
64 |
65 |
66 | ..\..\packages\Xam.Plugin.Media.2.3.0\lib\MonoAndroid10\Plugin.Media.Abstractions.dll
67 | True
68 |
69 |
70 | ..\..\packages\Plugin.Permissions.1.1.7\lib\MonoAndroid10\Plugin.Permissions.dll
71 | True
72 |
73 |
74 | ..\..\packages\Plugin.Permissions.1.1.7\lib\MonoAndroid10\Plugin.Permissions.Abstractions.dll
75 | True
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | ..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Animated.Vector.Drawable.dll
84 | True
85 |
86 |
87 | ..\..\packages\Xamarin.Android.Support.Design.23.3.0\lib\MonoAndroid43\Xamarin.Android.Support.Design.dll
88 | True
89 |
90 |
91 | ..\..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll
92 | True
93 |
94 |
95 | ..\..\packages\Xamarin.Android.Support.v7.AppCompat.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll
96 | True
97 |
98 |
99 | ..\..\packages\Xamarin.Android.Support.v7.CardView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.CardView.dll
100 | True
101 |
102 |
103 | ..\..\packages\Xamarin.Android.Support.v7.MediaRouter.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll
104 | True
105 |
106 |
107 | ..\..\packages\Xamarin.Android.Support.v7.RecyclerView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.RecyclerView.dll
108 | True
109 |
110 |
111 | ..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Vector.Drawable.dll
112 | True
113 |
114 |
115 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\MonoAndroid10\Xamarin.Forms.Core.dll
116 | True
117 |
118 |
119 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\MonoAndroid10\Xamarin.Forms.Platform.dll
120 | True
121 |
122 |
123 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll
124 | True
125 |
126 |
127 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll
128 | True
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 | {1825C5AF-CCF4-4348-9049-273B7C29F855}
160 | InvoiceIt
161 |
162 |
163 |
164 |
165 |
166 |
167 | 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}.
168 |
169 |
170 |
171 |
172 |
173 |
180 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.Content.PM;
5 | using Android.Runtime;
6 | using Android.Views;
7 | using Android.Widget;
8 | using Android.OS;
9 |
10 | namespace InvoiceIt.Droid
11 | {
12 | [Activity(Label = "InvoiceIt", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
13 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
14 | {
15 | protected override void OnCreate(Bundle bundle)
16 | {
17 | TabLayoutResource = Resource.Layout.Tabbar;
18 | ToolbarResource = Resource.Layout.Toolbar;
19 |
20 | base.OnCreate(bundle);
21 |
22 | global::Xamarin.Forms.Forms.Init(this, bundle);
23 | LoadApplication(new App());
24 | }
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Android.App;
4 | using Android.OS;
5 | using Android.Runtime;
6 | using Plugin.CurrentActivity;
7 |
8 | namespace InvoiceIt.Droid
9 | {
10 | //You can specify additional application information in this attribute
11 | [Application]
12 | public class MainApplication : Application, Application.IActivityLifecycleCallbacks
13 | {
14 | public MainApplication(IntPtr handle, JniHandleOwnership transer)
15 | :base(handle, transer)
16 | {
17 | }
18 |
19 | public override void OnCreate()
20 | {
21 | base.OnCreate();
22 | RegisterActivityLifecycleCallbacks(this);
23 | //A great place to initialize Xamarin.Insights and Dependency Services!
24 | }
25 |
26 | public override void OnTerminate()
27 | {
28 | base.OnTerminate();
29 | UnregisterActivityLifecycleCallbacks(this);
30 | }
31 |
32 | public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
33 | {
34 | CrossCurrentActivity.Current.Activity = activity;
35 | }
36 |
37 | public void OnActivityDestroyed(Activity activity)
38 | {
39 | }
40 |
41 | public void OnActivityPaused(Activity activity)
42 | {
43 | }
44 |
45 | public void OnActivityResumed(Activity activity)
46 | {
47 | CrossCurrentActivity.Current.Activity = activity;
48 | }
49 |
50 | public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
51 | {
52 | }
53 |
54 | public void OnActivityStarted(Activity activity)
55 | {
56 | CrossCurrentActivity.Current.Activity = activity;
57 | }
58 |
59 | public void OnActivityStopped(Activity activity)
60 | {
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("InvoiceIt.Droid")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("InvoiceIt.Droid")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
32 | // Add some common permissions, these can be removed if not needed
33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
35 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
51 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/drawable/icon.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/layout/Tabbar.axml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/layout/Toolbar.axml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/Resources/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
26 |
27 |
30 |
31 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.Droid/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace InvoiceIt.UWP
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 |
43 | #if DEBUG
44 | if (System.Diagnostics.Debugger.IsAttached)
45 | {
46 | this.DebugSettings.EnableFrameRateCounter = true;
47 | }
48 | #endif
49 |
50 | Frame rootFrame = Window.Current.Content as Frame;
51 |
52 | // Do not repeat app initialization when the Window already has content,
53 | // just ensure that the window is active
54 | if (rootFrame == null)
55 | {
56 | // Create a Frame to act as the navigation context and navigate to the first page
57 | rootFrame = new Frame();
58 |
59 | rootFrame.NavigationFailed += OnNavigationFailed;
60 |
61 | Xamarin.Forms.Forms.Init(e);
62 |
63 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
64 | {
65 | //TODO: Load state from previously suspended application
66 | }
67 |
68 | // Place the frame in the current Window
69 | Window.Current.Content = rootFrame;
70 | }
71 |
72 | if (rootFrame.Content == null)
73 | {
74 | // When the navigation stack isn't restored navigate to the first page,
75 | // configuring the new page by passing required information as a navigation
76 | // parameter
77 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
78 | }
79 | // Ensure the current window is active
80 | Window.Current.Activate();
81 | }
82 |
83 | ///
84 | /// Invoked when Navigation to a certain page fails
85 | ///
86 | /// The Frame which failed navigation
87 | /// Details about the navigation failure
88 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
89 | {
90 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
91 | }
92 |
93 | ///
94 | /// Invoked when application execution is being suspended. Application state is saved
95 | /// without knowing whether the application will be terminated or resumed with the contents
96 | /// of memory still intact.
97 | ///
98 | /// The source of the suspend request.
99 | /// Details about the suspend request.
100 | private void OnSuspending(object sender, SuspendingEventArgs e)
101 | {
102 | var deferral = e.SuspendingOperation.GetDeferral();
103 | //TODO: Save application state and stop any background activity
104 | deferral.Complete();
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.UWP/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/InvoiceIt.UWP.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}
8 | AppContainerExe
9 | Properties
10 | ExpenseIt.UWP
11 | ExpenseIt.UWP
12 | en-US
13 | UAP
14 | 10.0.10586.0
15 | 10.0.10586.0
16 | 14
17 | true
18 | 512
19 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
20 | Windows_TemporaryKey.pfx
21 |
22 |
23 | true
24 | bin\ARM\Debug\
25 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
26 | ;2008
27 | full
28 | ARM
29 | false
30 | prompt
31 | true
32 |
33 |
34 | bin\ARM\Release\
35 | TRACE;NETFX_CORE;WINDOWS_UWP
36 | true
37 | ;2008
38 | pdbonly
39 | ARM
40 | false
41 | prompt
42 | true
43 | true
44 |
45 |
46 | true
47 | bin\x64\Debug\
48 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
49 | ;2008
50 | full
51 | x64
52 | false
53 | prompt
54 | true
55 |
56 |
57 | bin\x64\Release\
58 | TRACE;NETFX_CORE;WINDOWS_UWP
59 | true
60 | ;2008
61 | pdbonly
62 | x64
63 | false
64 | prompt
65 | true
66 | true
67 |
68 |
69 | true
70 | bin\x86\Debug\
71 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
72 | ;2008
73 | full
74 | x86
75 | false
76 | prompt
77 | true
78 |
79 |
80 | bin\x86\Release\
81 | TRACE;NETFX_CORE;WINDOWS_UWP
82 | true
83 | ;2008
84 | pdbonly
85 | x86
86 | false
87 | prompt
88 | true
89 | true
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | App.xaml
98 |
99 |
100 | MainPage.xaml
101 |
102 |
103 |
104 |
105 |
106 | Designer
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | MSBuild:Compile
123 | Designer
124 |
125 |
126 | MSBuild:Compile
127 | Designer
128 |
129 |
130 |
131 |
132 | {1825C5AF-CCF4-4348-9049-273B7C29F855}
133 | InvoiceIt
134 |
135 |
136 |
137 | 14.0
138 |
139 |
140 |
147 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/InvoiceIt.UWP.nuget.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(UserProfile)\.nuget\packages\
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | namespace InvoiceIt.UWP
17 | {
18 | public sealed partial class MainPage
19 | {
20 | public MainPage()
21 | {
22 | this.InitializeComponent();
23 |
24 | LoadApplication(new InvoiceIt.App());
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | InvoiceIt.UWP
18 | xamarin
19 | Assets\StoreLogo.png
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("InvoiceIt.UWP")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("InvoiceIt.UWP")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.UWP/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0",
4 | "Xam.Plugin.Media": "2.3.0",
5 | "Xamarin.Forms": "2.3.0.107"
6 | },
7 | "frameworks": {
8 | "uap10.0": {}
9 | },
10 | "runtimes": {
11 | "win10-arm": {},
12 | "win10-arm-aot": {},
13 | "win10-x86": {},
14 | "win10-x86-aot": {},
15 | "win10-x64": {},
16 | "win10-x64-aot": {}
17 | }
18 | }
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace InvoiceIt.iOS
9 | {
10 | // The UIApplicationDelegate for the application. This class is responsible for launching the
11 | // User Interface of the application, as well as listening (and optionally responding) to
12 | // application events from iOS.
13 | [Register("AppDelegate")]
14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
15 | {
16 | //
17 | // This method is invoked when the application has loaded and is ready to run. In this
18 | // method you should instantiate the window, load the UI into it and then make the window
19 | // visible.
20 | //
21 | // You have 17 seconds to return from this method, or iOS will terminate your application.
22 | //
23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
24 | {
25 | global::Xamarin.Forms.Forms.Init();
26 | LoadApplication(new App());
27 |
28 | return base.FinishedLaunching(app, options);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UISupportedInterfaceOrientations
11 |
12 | UIInterfaceOrientationPortrait
13 | UIInterfaceOrientationLandscapeLeft
14 | UIInterfaceOrientationLandscapeRight
15 |
16 | UISupportedInterfaceOrientations~ipad
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationPortraitUpsideDown
20 | UIInterfaceOrientationLandscapeLeft
21 | UIInterfaceOrientationLandscapeRight
22 |
23 | MinimumOSVersion
24 | 6.0
25 | CFBundleDisplayName
26 | InvoiceIt
27 | CFBundleIdentifier
28 | com.yourcompany.InvoiceIt
29 | CFBundleVersion
30 | 1.0
31 | CFBundleIconFiles
32 |
33 | Icon-60@2x
34 | Icon-60@3x
35 | Icon-76
36 | Icon-76@2x
37 | Default
38 | Default@2x
39 | Default-568h@2x
40 | Default-Portrait
41 | Default-Portrait@2x
42 | Icon-Small-40
43 | Icon-Small-40@2x
44 | Icon-Small-40@3x
45 | Icon-Small
46 | Icon-Small@2x
47 | Icon-Small@3x
48 |
49 | UILaunchStoryboardName
50 | LaunchScreen
51 |
52 |
53 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/InvoiceIt.iOS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | 8.0.30703
7 | 2.0
8 | {B2F3F763-FECF-4681-A558-417662CE6A9B}
9 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | Exe
11 | ExpenseIt.iOS
12 | Resources
13 | ExpenseItiOS
14 |
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\iPhoneSimulator\Debug
22 | DEBUG
23 | prompt
24 | 4
25 | false
26 | i386, x86_64
27 | None
28 | true
29 |
30 |
31 | none
32 | true
33 | bin\iPhoneSimulator\Release
34 | prompt
35 | 4
36 | None
37 | i386, x86_64
38 | false
39 |
40 |
41 | true
42 | full
43 | false
44 | bin\iPhone\Debug
45 | DEBUG
46 | prompt
47 | 4
48 | false
49 | ARMv7, ARM64
50 | iPhone Developer
51 | true
52 | Entitlements.plist
53 |
54 |
55 | none
56 | true
57 | bin\iPhone\Release
58 | prompt
59 | 4
60 | ARMv7, ARM64
61 | false
62 | iPhone Developer
63 | Entitlements.plist
64 |
65 |
66 | none
67 | True
68 | bin\iPhone\Ad-Hoc
69 | prompt
70 | 4
71 | False
72 | ARMv7, ARM64
73 | True
74 | Automatic:AdHoc
75 | iPhone Distribution
76 | Entitlements.plist
77 |
78 |
79 | none
80 | True
81 | bin\iPhone\AppStore
82 | prompt
83 | 4
84 | False
85 | ARMv7, ARM64
86 | Automatic:AppStore
87 | iPhone Distribution
88 | Entitlements.plist
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | ..\..\packages\Xam.Plugin.Media.2.3.0\lib\Xamarin.iOS10\Plugin.Media.dll
122 | True
123 |
124 |
125 | ..\..\packages\Xam.Plugin.Media.2.3.0\lib\Xamarin.iOS10\Plugin.Media.Abstractions.dll
126 | True
127 |
128 |
129 |
130 |
131 |
132 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll
133 | True
134 |
135 |
136 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll
137 | True
138 |
139 |
140 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll
141 | True
142 |
143 |
144 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll
145 | True
146 |
147 |
148 |
149 |
150 |
151 | {1825C5AF-CCF4-4348-9049-273B7C29F855}
152 | InvoiceIt
153 |
154 |
155 |
156 |
157 |
158 |
159 | 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}.
160 |
161 |
162 |
163 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace InvoiceIt.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("InvoiceIt.iOS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("InvoiceIt.iOS")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default-Portrait.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Default@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-60@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-60@3x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-76.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-76@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small-40.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small-40@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small-40@3x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small@2x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/Icon-Small@3x.png
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/Resources/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/iTunesArtwork:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/iTunesArtwork
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/iTunesArtwork@2x:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CatalystCode/receipt-recognition/47edbd191105ea4392773f5c5ea06df45e13bc6b/MobileApp/ExpenseIt/ExpenseIt.iOS/iTunesArtwork@2x
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt.iOS/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/APIResponse.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace ExpenseIt
9 | {
10 | class APIResponse
11 | {
12 | [JsonProperty(PropertyName = "receipt_url")]
13 | public string Receipt_Url { get; set; }
14 |
15 | [JsonProperty(PropertyName = "success")]
16 | public bool Success { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | using Xamarin.Forms;
7 | using Xamarin.Forms.Xaml;
8 |
9 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)]
10 | namespace InvoiceIt
11 | {
12 | public partial class App : Application
13 | {
14 | public App()
15 | {
16 | InitializeComponent();
17 |
18 | MainPage = new NavigationPage(new InvoiceIt.InvoicesPage())
19 | {
20 | BarBackgroundColor = Color.FromHex("#03A9F4"),
21 | BarTextColor = Color.White
22 | };
23 | }
24 |
25 | protected override void OnStart()
26 | {
27 | // Handle when your app starts
28 | }
29 |
30 | protected override void OnSleep()
31 | {
32 | // Handle when your app sleeps
33 | }
34 |
35 | protected override void OnResume()
36 | {
37 | // Handle when your app resumes
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/CardViewCell.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 |
9 | namespace InvoiceIt
10 | {
11 | public class CardViewCell : ViewCell
12 | {
13 | public static readonly BindableProperty TextProperty =
14 | BindableProperty.Create(nameof(Text), typeof(string), typeof(CardViewCell), null, BindingMode.OneWay, propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
15 | {
16 | var ctrl = (CardViewCell)bindable;
17 | ctrl.Text = (string)newValue;
18 | });
19 |
20 | public string Text
21 | {
22 | get { return (string)GetValue(TextProperty); }
23 | set { SetValue(TextProperty, value); textLabel.Text = value; }
24 | }
25 |
26 | public static readonly BindableProperty DetailProperty =
27 | BindableProperty.Create(nameof(Detail), typeof(string), typeof(CardViewCell), null, BindingMode.OneWay, propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
28 | {
29 | var ctrl = (CardViewCell)bindable;
30 | ctrl.Detail = (string)newValue;
31 | });
32 |
33 | public string Detail
34 | {
35 | get { return (string)GetValue(DetailProperty); }
36 | set { SetValue(DetailProperty, value); detailTextLabel.Text = value; }
37 | }
38 |
39 |
40 | public static readonly BindableProperty Detail1Property =
41 | BindableProperty.Create(nameof(Detail1), typeof(string), typeof(CardViewCell), null, BindingMode.OneWay, propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
42 | {
43 | var ctrl = (CardViewCell)bindable;
44 | ctrl.Detail1 = (string)newValue;
45 | });
46 |
47 | public string Detail1
48 | {
49 | get { return (string)GetValue(Detail1Property); }
50 | set { SetValue(Detail1Property, value); detail1TextLabel.Text = value; }
51 | }
52 |
53 | public static readonly BindableProperty Detail2Property =
54 | BindableProperty.Create(nameof(Detail2), typeof(string), typeof(CardViewCell), null, BindingMode.OneWay, propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
55 | {
56 | var ctrl = (CardViewCell)bindable;
57 | ctrl.Detail2 = (string)newValue;
58 | });
59 |
60 | public string Detail2
61 | {
62 | get { return (string)GetValue(Detail2Property); }
63 | set { SetValue(Detail2Property, value); detail2TextLabel.Text = value; }
64 | }
65 |
66 | public static readonly BindableProperty Detail3Property =
67 | BindableProperty.Create(nameof(Detail3), typeof(string), typeof(CardViewCell), null, BindingMode.OneWay, propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
68 | {
69 | var ctrl = (CardViewCell)bindable;
70 | ctrl.Detail3 = (string)newValue;
71 | });
72 |
73 | public string Detail3
74 | {
75 | get { return (string)GetValue(Detail3Property); }
76 | set { SetValue(Detail3Property, value); detail3TextLabel.Text = value; }
77 | }
78 |
79 | public static readonly BindableProperty ImageSourceProperty =
80 | BindableProperty.Create(nameof(ImageSource), typeof(ImageSource), typeof(CardViewCell), null, BindingMode.OneWay, propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
81 | {
82 | var ctrl = (CardViewCell)bindable;
83 | ctrl.ImageSource = (ImageSource)newValue;
84 | });
85 |
86 | public ImageSource ImageSource
87 | {
88 | get { return (ImageSource)GetValue(ImageSourceProperty); }
89 | set { SetValue(ImageSourceProperty, value); image.Source = value; }
90 | }
91 |
92 |
93 | StackLayout layout;
94 | Image image;
95 | Label textLabel;
96 | Label detailTextLabel;
97 | private Label detail1TextLabel;
98 | private Label valueLabel3;
99 | private Label valueLabel2;
100 | private Label detail2TextLabel;
101 | private Label detail3TextLabel;
102 |
103 | public CardViewCell()
104 | {
105 | image = new Image
106 | {
107 | Aspect = Device.OnPlatform(Aspect.AspectFill, Aspect.AspectFill, Aspect.AspectFit),
108 | HorizontalOptions = LayoutOptions.FillAndExpand,
109 | VerticalOptions = LayoutOptions.StartAndExpand,
110 | WidthRequest = 220,
111 | HeightRequest = 200,
112 | Source = ImageSource.FromUri(new Uri("https://avatars3.githubusercontent.com/u/1091304?v=3&s=460"))
113 | };
114 |
115 | textLabel = new Label
116 | {
117 | FontSize = Device.OnPlatform(15, 15, 15),
118 | TextColor = Device.OnPlatform(Color.FromHex("030303"), Color.FromHex("030303"), Color.FromHex("030303")),
119 | HorizontalOptions = LayoutOptions.Start,
120 | HorizontalTextAlignment = TextAlignment.Start,
121 | Margin = Device.OnPlatform(new Thickness(12, 10, 12, 4), new Thickness(20, 10, 20, 5), new Thickness(20, 10, 20, 5)),
122 | LineBreakMode = LineBreakMode.WordWrap,
123 | VerticalOptions = LayoutOptions.End,
124 | Text = "Pierce Boggan"
125 | };
126 |
127 |
128 | detail1TextLabel = new Label
129 | {
130 | FontSize = Device.OnPlatform(15, 15, 15),
131 | TextColor = Device.OnPlatform(Color.FromHex("030303"), Color.FromHex("030303"), Color.FromHex("030303")),
132 | HorizontalOptions = LayoutOptions.Start,
133 | HorizontalTextAlignment = TextAlignment.Start,
134 | Margin = Device.OnPlatform(new Thickness(12, 10, 12, 4), new Thickness(20, 10, 20, 5), new Thickness(20, 10, 20, 5)),
135 | LineBreakMode = LineBreakMode.WordWrap,
136 | VerticalOptions = LayoutOptions.End,
137 | Text = "Pierce Boggan"
138 | };
139 |
140 |
141 | detail2TextLabel = new Label
142 | {
143 | FontSize = Device.OnPlatform(15, 15, 15),
144 | TextColor = Device.OnPlatform(Color.FromHex("030303"), Color.FromHex("030303"), Color.FromHex("030303")),
145 | HorizontalOptions = LayoutOptions.Start,
146 | HorizontalTextAlignment = TextAlignment.Start,
147 | Margin = Device.OnPlatform(new Thickness(12, 10, 12, 4), new Thickness(20, 10, 20, 5), new Thickness(20, 10, 20, 5)),
148 | LineBreakMode = LineBreakMode.WordWrap,
149 | VerticalOptions = LayoutOptions.End,
150 | Text = "Pierce Boggan"
151 | };
152 |
153 | detailTextLabel = new Label
154 | {
155 | FontSize = Device.OnPlatform(13, 13, 13),
156 | TextColor = Device.OnPlatform(Color.FromHex("8F8E94"), Color.FromHex("8F8E94"), Color.FromHex("8F8E94")),
157 | HorizontalOptions = LayoutOptions.Start,
158 | HorizontalTextAlignment = TextAlignment.Start,
159 | Margin = Device.OnPlatform(new Thickness(12, 0, 10, 12), new Thickness(20, 0, 20, 20), new Thickness(20, 0, 20, 20)),
160 | LineBreakMode = LineBreakMode.WordWrap,
161 | VerticalOptions = LayoutOptions.End,
162 | Text = "pierce@xamarin.com"
163 | };
164 |
165 |
166 | detail3TextLabel = new Label
167 | {
168 | FontSize = Device.OnPlatform(15, 15, 15),
169 | TextColor = Device.OnPlatform(Color.FromHex("030303"), Color.FromHex("030303"), Color.FromHex("030303")),
170 | HorizontalOptions = LayoutOptions.Start,
171 | HorizontalTextAlignment = TextAlignment.Start,
172 | Margin = Device.OnPlatform(new Thickness(12, 10, 12, 4), new Thickness(20, 10, 20, 5), new Thickness(20, 10, 20, 5)),
173 | LineBreakMode = LineBreakMode.WordWrap,
174 | VerticalOptions = LayoutOptions.End,
175 | Text = "Pierce Boggan"
176 | };
177 |
178 | layout = new StackLayout
179 | {
180 | BackgroundColor = Color.White,
181 | Spacing = 0,
182 | Children = { image, detail1TextLabel, detail2TextLabel, detail3TextLabel, textLabel }
183 | };
184 |
185 | View = layout;
186 | }
187 |
188 | protected override void OnBindingContextChanged()
189 | {
190 | base.OnBindingContextChanged();
191 |
192 | View.BindingContext = BindingContext;
193 | }
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/Expense.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Plugin.Media.Abstractions;
7 |
8 | using static System.DateTime;
9 | using static System.String;
10 |
11 | namespace InvoiceIt
12 | {
13 | public class Invoice
14 | {
15 | public DateTime TimeStamp { get; set; } = UtcNow;
16 | public string Photo { get; set; } = Empty;
17 | public string ScoredLabel1 { get; set; }
18 | public string ScoredLabel2 { get; set; }
19 | public string ScoredLabel3 { get; set; }
20 | }
21 |
22 | public class MLOutputItem
23 | {
24 | public float Probability { get; set; }
25 | public string Category { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/InvoiceIt.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 10.0
6 | Debug
7 | AnyCPU
8 | {1825C5AF-CCF4-4348-9049-273B7C29F855}
9 | Library
10 | Properties
11 | ExpenseIt
12 | ExpenseIt
13 | v4.5
14 | Profile111
15 | 512
16 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
17 |
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 | App.xaml
41 |
42 |
43 |
44 |
45 |
46 | InvoicesPage.xaml
47 |
48 |
49 |
50 |
51 |
52 |
53 | Designer
54 | MSBuild:UpdateDesignTimeXaml
55 |
56 |
57 | Designer
58 | MSBuild:UpdateDesignTimeXaml
59 |
60 |
61 |
62 |
63 | ..\..\packages\Microsoft.ProjectOxford.Vision.1.0.354\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Microsoft.ProjectOxford.Vision.dll
64 | True
65 |
66 |
67 | ..\..\packages\Newtonsoft.Json.8.0.2\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll
68 | True
69 |
70 |
71 | ..\..\packages\Xam.Plugin.Media.2.3.0\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Plugin.Media.dll
72 | True
73 |
74 |
75 | ..\..\packages\Xam.Plugin.Media.2.3.0\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Plugin.Media.Abstractions.dll
76 | True
77 |
78 |
79 | ..\..\packages\System.Net.Http.Formatting.Extension.5.2.3.0\lib\System.Net.Http.Extensions.dll
80 | True
81 |
82 |
83 | ..\..\packages\System.Net.Http.Formatting.Extension.5.2.3.0\lib\System.Net.Http.Formatting.dll
84 | True
85 |
86 |
87 | ..\..\packages\System.Net.Http.Formatting.Extension.5.2.3.0\lib\System.Net.Http.Primitives.dll
88 | True
89 |
90 |
91 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll
92 | True
93 |
94 |
95 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Platform.dll
96 | True
97 |
98 |
99 | ..\..\packages\Xamarin.Forms.2.3.0.107\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Xaml.dll
100 | True
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | 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}.
112 |
113 |
114 |
115 |
116 |
117 |
124 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/InvoicesPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/InvoicesPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Xamarin.Forms;
7 |
8 | namespace InvoiceIt
9 | {
10 | public partial class InvoicesPage : ContentPage
11 | {
12 | public InvoicesPage()
13 | {
14 | InitializeComponent();
15 |
16 | BindingContext = new InvoicesViewModel();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/InvoicesViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | using Xamarin.Forms;
9 |
10 | using Plugin.Media;
11 | using Plugin.Media.Abstractions;
12 |
13 | using Microsoft.ProjectOxford.Vision;
14 | using Microsoft.ProjectOxford.Vision.Contract;
15 | using System.ComponentModel;
16 | using System.Diagnostics;
17 |
18 | using static System.Diagnostics.Debug;
19 | using System.Runtime.CompilerServices;
20 | using System.Net.Http.Headers;
21 | using System.Net.Http;
22 | using System.IO;
23 | using Newtonsoft.Json.Linq;
24 | using Newtonsoft.Json;
25 | using Newtonsoft.Json.Converters;
26 | using ExpenseIt;
27 |
28 | namespace InvoiceIt
29 | {
30 | public class InvoicesViewModel : INotifyPropertyChanged
31 | {
32 | public ObservableCollection Invoices { get; } = new ObservableCollection();
33 |
34 | public string Message { get; set; } = "Hello World!";
35 |
36 | Command addInvoiceCommand = null;
37 | public Command AddInvoiceCommand =>
38 | addInvoiceCommand ?? (addInvoiceCommand = new Command(async () => await ExecuteAddInvoiceCommandAsync()));
39 |
40 |
41 | async Task ExecuteAddInvoiceCommandAsync()
42 | {
43 | try
44 | {
45 | IsBusy = true;
46 | // 1. Add camera logic.
47 | await CrossMedia.Current.Initialize();
48 |
49 | MediaFile photo;
50 | if (CrossMedia.Current.IsCameraAvailable)
51 | {
52 | photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
53 | {
54 | Directory = "Receipts",
55 | Name = "Receipt"
56 | });
57 | }
58 | else
59 | {
60 | photo = await CrossMedia.Current.PickPhotoAsync();
61 | }
62 |
63 | if (photo == null)
64 | {
65 | PrintStatus("Photo was null :(");
66 | return;
67 | }
68 |
69 |
70 | byte[] data = ReadFully(photo.GetStream());
71 |
72 | using (var client = new HttpClient())
73 | {
74 | using (var content = new MultipartFormDataContent())
75 | {
76 |
77 | var fileContent = new ByteArrayContent(data);
78 | fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") // attachment?
79 | {
80 | Name = "file", // required?
81 | FileName = "test.jpg"
82 | };
83 | content.Add(fileContent);
84 | //IsBusy = false;
85 |
86 | var requestUri = "http://at-dev-vm-zxpapi-01.westus.cloudapp.azure.com/v1.0/groups/1/receipts";
87 | //var requestUri = "http://requestb.in/11y6k4z1";
88 | var response = await client.PostAsync(requestUri, content);
89 | if (response.IsSuccessStatusCode)
90 | {
91 | string result = await response.Content.ReadAsStringAsync();
92 | APIResponse apiResponse = JsonConvert.DeserializeObject(result);
93 |
94 | using (var clientML = new HttpClient())
95 | {
96 | string temp = apiResponse.Receipt_Url.Replace("https", "http");
97 |
98 | var scoreRequest = new
99 | {
100 |
101 | Inputs = new Dictionary>>() {
102 | {
103 | "input1",
104 | new List>() {
105 | new Dictionary() {
106 | //{ "Category", "" },
107 | { "Url", temp},
108 | }
109 | }
110 | },
111 | },
112 | GlobalParameters = new Dictionary()
113 | {
114 | }
115 | };
116 |
117 | var jsonToSend = JsonConvert.SerializeObject(scoreRequest);
118 | var body = new StringContent(jsonToSend, Encoding.UTF8, "application/json");
119 |
120 | const string apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Replace this with the API key for the web service
121 | clientML.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
122 | clientML.BaseAddress = new Uri("https://xxx.services.azureml.net/subscriptions/xxxxxxxxx/services/xxxxxxx/execute?api-version=2.0&format=swagger");
123 |
124 | var responseML = await clientML.PostAsync("", body);
125 |
126 | if (responseML.IsSuccessStatusCode)
127 | {
128 | string resultML = await responseML.Content.ReadAsStringAsync();
129 | // Convert JSON to object
130 | MLResponse obj = JsonConvert.DeserializeObject(resultML);
131 |
132 | var outPuts = new List(6);
133 |
134 | outPuts.Add(new MLOutputItem { Category = "Clothes and Accessories", Probability = (float)obj.Results.Output[0].ClothesAndAccessoriesProbability });
135 | outPuts.Add(new MLOutputItem { Category = "Daily Snacks", Probability = (float)obj.Results.Output[0].DailySnacksProbability });
136 | outPuts.Add(new MLOutputItem { Category = "Dining Out", Probability = (float)obj.Results.Output[0].DiningOutProbability });
137 | outPuts.Add(new MLOutputItem { Category = "Entertainment", Probability = (float)obj.Results.Output[0].EntertainmentProbability });
138 | outPuts.Add(new MLOutputItem { Category = "Fuel", Probability = (float)obj.Results.Output[0].FuelProbability });
139 | outPuts.Add(new MLOutputItem { Category = "Groceries", Probability = (float)obj.Results.Output[0].GroceriesProbability });
140 |
141 | outPuts = outPuts.OrderByDescending(x => x.Probability).ToList();
142 |
143 | Invoices.Add(new Invoice
144 | {
145 | ScoredLabel1 = outPuts[0].Category + " : " + outPuts[0].Probability ,
146 | ScoredLabel2 = outPuts[1].Category + " : " + outPuts[1].Probability ,
147 | ScoredLabel3 = outPuts[2].Category + " : " + outPuts[2].Probability ,
148 | Photo = photo.Path,
149 | TimeStamp = DateTime.Now
150 | });
151 |
152 | }
153 | }
154 | }
155 | }
156 | }
157 | }
158 | catch (Exception ex)
159 | {
160 |
161 | }
162 | finally
163 | {
164 | IsBusy = false;
165 | }
166 |
167 | }
168 |
169 |
170 | public void PrintStatus(string helloWorld)
171 | {
172 | if (helloWorld == null)
173 | throw new ArgumentNullException(nameof(helloWorld));
174 |
175 | WriteLine(helloWorld);
176 | }
177 |
178 | public static byte[] ReadFully(Stream input)
179 | {
180 | byte[] buffer = new byte[16 * 1024];
181 | using (MemoryStream ms = new MemoryStream())
182 | {
183 | int read;
184 | while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
185 | {
186 | ms.Write(buffer, 0, read);
187 | }
188 | return ms.ToArray();
189 | }
190 | }
191 |
192 | public event PropertyChangedEventHandler PropertyChanged;
193 | void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
194 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
195 |
196 |
197 | bool busy;
198 | public bool IsBusy
199 | {
200 | get { return busy; }
201 | set
202 | {
203 | if (busy == value)
204 | return;
205 |
206 | busy = value;
207 | OnPropertyChanged();
208 | OnPropertyChanged(nameof(Message));
209 | }
210 | }
211 |
212 |
213 | }
214 | }
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/MLResponseOutput.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace ExpenseIt
9 | {
10 |
11 | public class MLResponseOutput
12 | {
13 | [JsonProperty(PropertyName = "Scored Probabilities for Class \"clothes and accessories\"")]
14 | public double ClothesAndAccessoriesProbability { get; set; }
15 | [JsonProperty(PropertyName = "Scored Probabilities for Class \"daily snack\"")]
16 | public double DailySnacksProbability { get; set; }
17 | [JsonProperty(PropertyName = "Scored Probabilities for Class \"dining out\"")]
18 | public double DiningOutProbability { get; set; }
19 | [JsonProperty(PropertyName = "Scored Probabilities for Class \"entertinement\"")]
20 | public double EntertainmentProbability { get; set; }
21 | [JsonProperty(PropertyName = "Scored Probabilities for Class \"fuel\"")]
22 | public double FuelProbability { get; set; }
23 | [JsonProperty(PropertyName = "Scored Probabilities for Class \"groceries\"")]
24 | public double GroceriesProbability { get; set; }
25 | [JsonProperty(PropertyName = "Scored Labels")]
26 | public string ScoredLabels { get; set; }
27 | }
28 |
29 | public class MLResponseResults
30 | {
31 | [JsonProperty(PropertyName = "output1")]
32 | public List Output { get; set; }
33 | }
34 |
35 | public class MLResponse
36 | {
37 | public MLResponseResults Results { get; set; }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Resources;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("InvoiceIt")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("InvoiceIt")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: NeutralResourcesLanguage("en")]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MobileApp/ExpenseIt/ExpenseIt/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MobileApp/InvoiceIt.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceIt.Droid", "ExpenseIt\ExpenseIt.Droid\InvoiceIt.Droid.csproj", "{C4588DE8-DA54-43BC-8814-374CE67FF7B9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceIt.iOS", "ExpenseIt\ExpenseIt.iOS\InvoiceIt.iOS.csproj", "{B2F3F763-FECF-4681-A558-417662CE6A9B}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceIt.UWP", "ExpenseIt\ExpenseIt.UWP\InvoiceIt.UWP.csproj", "{07F9A8B3-5E21-4801-8FA5-F0928B847292}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvoiceIt", "ExpenseIt\ExpenseIt\InvoiceIt.csproj", "{1825C5AF-CCF4-4348-9049-273B7C29F855}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
17 | Ad-Hoc|ARM = Ad-Hoc|ARM
18 | Ad-Hoc|iPhone = Ad-Hoc|iPhone
19 | Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
20 | Ad-Hoc|x64 = Ad-Hoc|x64
21 | Ad-Hoc|x86 = Ad-Hoc|x86
22 | AppStore|Any CPU = AppStore|Any CPU
23 | AppStore|ARM = AppStore|ARM
24 | AppStore|iPhone = AppStore|iPhone
25 | AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
26 | AppStore|x64 = AppStore|x64
27 | AppStore|x86 = AppStore|x86
28 | Debug|Any CPU = Debug|Any CPU
29 | Debug|ARM = Debug|ARM
30 | Debug|iPhone = Debug|iPhone
31 | Debug|iPhoneSimulator = Debug|iPhoneSimulator
32 | Debug|x64 = Debug|x64
33 | Debug|x86 = Debug|x86
34 | Release|Any CPU = Release|Any CPU
35 | Release|ARM = Release|ARM
36 | Release|iPhone = Release|iPhone
37 | Release|iPhoneSimulator = Release|iPhoneSimulator
38 | Release|x64 = Release|x64
39 | Release|x86 = Release|x86
40 | EndGlobalSection
41 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
42 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
43 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
44 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
45 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
46 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
47 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU
48 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
49 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
50 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
51 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
52 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
53 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
54 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
55 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|x64.Build.0 = Release|Any CPU
56 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU
57 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
58 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|x86.Build.0 = Release|Any CPU
59 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU
60 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
61 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|Any CPU.Build.0 = Release|Any CPU
62 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
63 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|ARM.ActiveCfg = Release|Any CPU
64 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|ARM.Build.0 = Release|Any CPU
65 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|ARM.Deploy.0 = Release|Any CPU
66 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|iPhone.ActiveCfg = Release|Any CPU
67 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|iPhone.Build.0 = Release|Any CPU
68 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|iPhone.Deploy.0 = Release|Any CPU
69 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
70 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
71 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
72 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|x64.ActiveCfg = Release|Any CPU
73 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|x64.Build.0 = Release|Any CPU
74 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|x64.Deploy.0 = Release|Any CPU
75 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|x86.ActiveCfg = Release|Any CPU
76 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|x86.Build.0 = Release|Any CPU
77 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.AppStore|x86.Deploy.0 = Release|Any CPU
78 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
79 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
80 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
81 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|ARM.ActiveCfg = Debug|Any CPU
82 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|ARM.Build.0 = Debug|Any CPU
83 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|ARM.Deploy.0 = Debug|Any CPU
84 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|iPhone.ActiveCfg = Debug|Any CPU
85 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|iPhone.Build.0 = Debug|Any CPU
86 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|iPhone.Deploy.0 = Debug|Any CPU
87 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
88 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
89 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
90 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|x64.ActiveCfg = Debug|Any CPU
91 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|x64.Build.0 = Debug|Any CPU
92 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|x64.Deploy.0 = Debug|Any CPU
93 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|x86.ActiveCfg = Debug|Any CPU
94 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|x86.Build.0 = Debug|Any CPU
95 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Debug|x86.Deploy.0 = Debug|Any CPU
96 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
97 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|Any CPU.Build.0 = Release|Any CPU
98 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|Any CPU.Deploy.0 = Release|Any CPU
99 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|ARM.ActiveCfg = Release|Any CPU
100 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|ARM.Build.0 = Release|Any CPU
101 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|ARM.Deploy.0 = Release|Any CPU
102 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|iPhone.ActiveCfg = Release|Any CPU
103 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|iPhone.Build.0 = Release|Any CPU
104 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|iPhone.Deploy.0 = Release|Any CPU
105 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
106 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
107 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
108 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|x64.ActiveCfg = Release|Any CPU
109 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|x64.Build.0 = Release|Any CPU
110 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|x64.Deploy.0 = Release|Any CPU
111 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|x86.ActiveCfg = Release|Any CPU
112 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|x86.Build.0 = Release|Any CPU
113 | {C4588DE8-DA54-43BC-8814-374CE67FF7B9}.Release|x86.Deploy.0 = Release|Any CPU
114 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
115 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
116 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
117 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
118 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
119 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
120 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
121 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
122 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
123 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|ARM.ActiveCfg = AppStore|iPhone
124 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
125 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|iPhone.Build.0 = AppStore|iPhone
126 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
127 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
128 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|x64.ActiveCfg = AppStore|iPhone
129 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.AppStore|x86.ActiveCfg = AppStore|iPhone
130 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|Any CPU.ActiveCfg = Debug|iPhone
131 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|Any CPU.Build.0 = Debug|iPhone
132 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|ARM.ActiveCfg = Debug|iPhone
133 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|iPhone.ActiveCfg = Debug|iPhone
134 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|iPhone.Build.0 = Debug|iPhone
135 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
136 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
137 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|x64.ActiveCfg = Debug|iPhone
138 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Debug|x86.ActiveCfg = Debug|iPhone
139 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|Any CPU.ActiveCfg = Release|iPhone
140 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|ARM.ActiveCfg = Release|iPhone
141 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|iPhone.ActiveCfg = Release|iPhone
142 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|iPhone.Build.0 = Release|iPhone
143 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
144 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
145 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|x64.ActiveCfg = Release|iPhone
146 | {B2F3F763-FECF-4681-A558-417662CE6A9B}.Release|x86.ActiveCfg = Release|iPhone
147 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86
148 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|Any CPU.Build.0 = Release|x86
149 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|Any CPU.Deploy.0 = Release|x86
150 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|ARM.ActiveCfg = Release|ARM
151 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|ARM.Build.0 = Release|ARM
152 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|ARM.Deploy.0 = Release|ARM
153 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|iPhone.ActiveCfg = Release|x86
154 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|iPhone.Build.0 = Release|x86
155 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|iPhone.Deploy.0 = Release|x86
156 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86
157 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86
158 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x86
159 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|x64.ActiveCfg = Release|x64
160 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|x64.Build.0 = Release|x64
161 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|x64.Deploy.0 = Release|x64
162 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|x86.ActiveCfg = Release|x86
163 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|x86.Build.0 = Release|x86
164 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Ad-Hoc|x86.Deploy.0 = Release|x86
165 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|Any CPU.ActiveCfg = Release|x86
166 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|Any CPU.Build.0 = Release|x86
167 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|Any CPU.Deploy.0 = Release|x86
168 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|ARM.ActiveCfg = Release|ARM
169 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|ARM.Build.0 = Release|ARM
170 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|ARM.Deploy.0 = Release|ARM
171 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|iPhone.ActiveCfg = Release|x86
172 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|iPhone.Build.0 = Release|x86
173 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|iPhone.Deploy.0 = Release|x86
174 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86
175 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|iPhoneSimulator.Build.0 = Release|x86
176 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|iPhoneSimulator.Deploy.0 = Release|x86
177 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|x64.ActiveCfg = Release|x64
178 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|x64.Build.0 = Release|x64
179 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|x64.Deploy.0 = Release|x64
180 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|x86.ActiveCfg = Release|x86
181 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|x86.Build.0 = Release|x86
182 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.AppStore|x86.Deploy.0 = Release|x86
183 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|Any CPU.ActiveCfg = Debug|x86
184 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|Any CPU.Build.0 = Debug|x86
185 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|Any CPU.Deploy.0 = Debug|x86
186 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|ARM.ActiveCfg = Debug|ARM
187 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|ARM.Build.0 = Debug|ARM
188 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|ARM.Deploy.0 = Debug|ARM
189 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|iPhone.ActiveCfg = Debug|x86
190 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
191 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|iPhoneSimulator.Build.0 = Debug|x86
192 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86
193 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|x64.ActiveCfg = Debug|x64
194 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|x64.Build.0 = Debug|x64
195 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|x64.Deploy.0 = Debug|x64
196 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|x86.ActiveCfg = Debug|x86
197 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|x86.Build.0 = Debug|x86
198 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Debug|x86.Deploy.0 = Debug|x86
199 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|Any CPU.ActiveCfg = Release|x86
200 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|ARM.ActiveCfg = Release|ARM
201 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|ARM.Build.0 = Release|ARM
202 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|ARM.Deploy.0 = Release|ARM
203 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|iPhone.ActiveCfg = Release|x86
204 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|iPhoneSimulator.ActiveCfg = Release|x86
205 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|x64.ActiveCfg = Release|x64
206 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|x64.Build.0 = Release|x64
207 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|x64.Deploy.0 = Release|x64
208 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|x86.ActiveCfg = Release|x86
209 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|x86.Build.0 = Release|x86
210 | {07F9A8B3-5E21-4801-8FA5-F0928B847292}.Release|x86.Deploy.0 = Release|x86
211 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
212 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
213 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
214 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
215 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
216 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
217 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
218 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
219 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
220 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|x64.Build.0 = Release|Any CPU
221 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
222 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Ad-Hoc|x86.Build.0 = Release|Any CPU
223 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
224 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|Any CPU.Build.0 = Release|Any CPU
225 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|ARM.ActiveCfg = Release|Any CPU
226 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|ARM.Build.0 = Release|Any CPU
227 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|iPhone.ActiveCfg = Release|Any CPU
228 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|iPhone.Build.0 = Release|Any CPU
229 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
230 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
231 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|x64.ActiveCfg = Release|Any CPU
232 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|x64.Build.0 = Release|Any CPU
233 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|x86.ActiveCfg = Release|Any CPU
234 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.AppStore|x86.Build.0 = Release|Any CPU
235 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
236 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|Any CPU.Build.0 = Debug|Any CPU
237 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|ARM.ActiveCfg = Debug|Any CPU
238 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|ARM.Build.0 = Debug|Any CPU
239 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|iPhone.ActiveCfg = Debug|Any CPU
240 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|iPhone.Build.0 = Debug|Any CPU
241 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
242 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
243 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|x64.ActiveCfg = Debug|Any CPU
244 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|x64.Build.0 = Debug|Any CPU
245 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|x86.ActiveCfg = Debug|Any CPU
246 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Debug|x86.Build.0 = Debug|Any CPU
247 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|Any CPU.ActiveCfg = Release|Any CPU
248 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|Any CPU.Build.0 = Release|Any CPU
249 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|ARM.ActiveCfg = Release|Any CPU
250 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|ARM.Build.0 = Release|Any CPU
251 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|iPhone.ActiveCfg = Release|Any CPU
252 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|iPhone.Build.0 = Release|Any CPU
253 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
254 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
255 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|x64.ActiveCfg = Release|Any CPU
256 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|x64.Build.0 = Release|Any CPU
257 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|x86.ActiveCfg = Release|Any CPU
258 | {1825C5AF-CCF4-4348-9049-273B7C29F855}.Release|x86.Build.0 = Release|Any CPU
259 | EndGlobalSection
260 | GlobalSection(SolutionProperties) = preSolution
261 | HideSolutionNode = FALSE
262 | EndGlobalSection
263 | EndGlobal
264 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # receipt-recognition
2 | Purpose: Predict type of expenses from imaged receipt, using Microsoft's OCR and AzureML.
3 |
4 | Accompanying [post](https://www.microsoft.com/developerblog/real-life-code/2017/01/02/expense-recognition.html).
5 |
6 | ML/Data Prep (Python):
7 | ----------------------
8 | 1. ORC.py contains code for converting unstructured image data into structured text data, which is then used to build a predictive model. The code is then adapted so that it can be hosted within Azure ML's Python Module and make the modelling process self-contained within Azure ML Studio.
9 |
10 | 2. This model is trained on ~1100 imaged American receipts for categories: Dining, snack, clothes, feul, groceries, entertainment
11 |
12 | Mobile App (Xamarin):
13 | ---------------------
14 | This is a single page Xamarin Forms based cross platform mobile application which takes an image and calls the partner(Agitare) api to store it in Azure blob storage. Once we get a stored URL to the image, we then pass this URL to Machine learning web service end point to obtain probability scores of different classification groups. The results are shown in a CardViewCell control in a Xamarin forms page. The app uses MVVM pattern to implement this functionality.
15 |
16 |
--------------------------------------------------------------------------------
/ocr-from-url.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Wed Nov 2 10:28:18 2016
4 | @author: chyam
5 | purpose: load images from blob storage, post to Microsoft OCR, save results, populate 'text' to .tsv file.
6 | """
7 | ### Error: UnicodeEncodeError: 'charmap' codec can't encode character
8 | ### Fixes: at windows console, type chcp 65001, press enter
9 |
10 | from __future__ import print_function
11 | from azure.storage.blob import BlockBlobService
12 | from azure.storage.blob import PublicAccess
13 | import configparser
14 | import time
15 | import requests
16 | import json
17 | import pandas as pd
18 | from io import StringIO
19 |
20 | _url = 'https://api.projectoxford.ai/vision/v1.0/ocr'
21 | _maxNumRetries = 10
22 |
23 | def main():
24 |
25 | # Get credential
26 | parser = configparser.ConfigParser()
27 | parser.read('config.ini')
28 | STORAGE_ACCOUNT_NAME = parser.get('credential', 'STORAGE_ACCOUNT_NAME')
29 | STORAGE_ACCOUNT_KEY = parser.get('credential', 'STORAGE_ACCOUNT_KEY')
30 | CONTAINER_NAME = parser.get('credential', 'CONTAINER_NAME')
31 | CONTAINER_NAME_METADATA = parser.get('credential', 'CONTAINER_NAME_METADATA')
32 | VISION_API_KEY = parser.get('credential', 'VISION_API_KEY') # need to use Agitare account
33 | CONTAINER_NAME_OCR_2 = parser.get('credential', 'CONTAINER_NAME_OCR_2')
34 | CONTAINER_NAME_STRUCTUREDDATA = parser.get('credential', 'CONTAINER_NAME_STRUCTUREDDATA')
35 |
36 | # access to bloob
37 | block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
38 | block_blob_service.set_container_acl(CONTAINER_NAME, public_access=PublicAccess.Container)
39 |
40 | # empty dataframe
41 | df = pd.DataFrame({'Text' : [], 'Category' : [], 'ReceiptID' : []})
42 |
43 | # get url and label from file
44 | blob_text = block_blob_service.get_blob_to_text(CONTAINER_NAME_METADATA, 'image-url-6-classes.tsv'); #print(blob_text.content)
45 | df_url_label = pd.DataFrame.from_csv(StringIO(blob_text.content), index_col=None, sep='\t'); #print(df_url_label.shape); print(df_url_label)
46 |
47 | for index, row in df_url_label.iterrows():
48 | #print(row['Category'])
49 | #print(row['Url'])
50 |
51 | imageurl = row['Url']
52 | # OCR parameters
53 | params = { 'language': 'en', 'detectOrientation ': 'true'}
54 | headers = dict()
55 | headers['Ocp-Apim-Subscription-Key'] = VISION_API_KEY
56 | headers['Content-Type'] = 'application/json'
57 |
58 | image_url = { 'url': imageurl } ;
59 | image_file = None
60 | result = processRequest( image_url, image_file, headers, params )
61 |
62 | if result is not None:
63 | #print(result)
64 | result_str = json.dumps(result); #print(result_str)
65 |
66 | # write result into blob
67 | ocrblobname = imageurl[-17:-3] + 'json'
68 | block_blob_service.create_blob_from_text(CONTAINER_NAME_OCR_2, ocrblobname, result_str)
69 | # extract text
70 | text = extractText(result); #print (text)
71 |
72 | # populate dataframe
73 | df.loc[index,'Text'] = text
74 | else:
75 | # populate dataframe
76 | df.loc[index,'Text'] = None
77 |
78 | df.loc[index,'Category'] = row['Category']
79 | df.loc[index,'ReceiptID'] = imageurl[-17:-3]
80 |
81 | # write dataframe to blob
82 | print("-----------------------")
83 | df_str = df.to_csv(sep='\t', index=False);
84 |
85 | dfblobname = 'dataframe_6_classes_url.tsv'
86 | block_blob_service.create_blob_from_text(CONTAINER_NAME_STRUCTUREDDATA, dfblobname, df_str)
87 |
88 | return
89 |
90 | def extractText(result):
91 | text = ""
92 | for region in result['regions']:
93 | for line in region['lines']:
94 | for word in line['words']:
95 | #print (word.get('text'))
96 | text = text + " " + word.get('text')
97 | return text
98 |
99 | def processRequest( image_url, image_file, headers, params ):
100 |
101 | """
102 | Ref: https://github.com/Microsoft/Cognitive-Vision-Python/blob/master/Jupyter%20Notebook/Computer%20Vision%20API%20Example.ipynb
103 | Helper function to process the request to Project Oxford
104 | Parameters:
105 | json: Used when processing images from its URL. See API Documentation
106 | data: Used when processing image read from disk. See API Documentation
107 | headers: Used to pass the key information and the data type request
108 | """
109 |
110 | retries = 0
111 | result = None
112 |
113 | while True:
114 |
115 | response = requests.request( 'post', _url, json = image_url, data = image_file, headers = headers, params = params )
116 |
117 | if response.status_code == 429:
118 |
119 | print( "Message: %s" % ( response.json()['message'] ) )
120 |
121 | if retries <= _maxNumRetries:
122 | time.sleep(1)
123 | retries += 1
124 | continue
125 | else:
126 | print( 'Error: failed after retrying!' )
127 | break
128 |
129 | elif response.status_code == 200 or response.status_code == 201:
130 |
131 | if 'content-length' in response.headers and int(response.headers['content-length']) == 0:
132 | result = None
133 | elif 'content-type' in response.headers and isinstance(response.headers['content-type'], str):
134 | if 'application/json' in response.headers['content-type'].lower():
135 | result = response.json() if response.content else None
136 | elif 'image' in response.headers['content-type'].lower():
137 | result = response.content
138 | else:
139 | print(response.json())
140 | print( "Error code: %d" % ( response.status_code ) );
141 | print( "Message: %s" % ( response.json()['message'] ) );
142 |
143 | break
144 |
145 | return result
146 |
147 | if __name__ == '__main__':
148 | main()
--------------------------------------------------------------------------------
/ocr.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Wed Nov 2 10:28:18 2016
4 | @author: chyam
5 | purpose: load images from blob storage, post to Microsoft OCR, save results, populate 'text' to .tsv file.
6 | """
7 | ### Error: UnicodeEncodeError: 'charmap' codec can't encode character
8 | ### Fixes: at windows console, type chcp 65001, press enter
9 |
10 | from __future__ import print_function
11 | from azure.storage.blob import BlockBlobService
12 | from azure.storage.blob import PublicAccess
13 | import configparser
14 | import time
15 | import requests
16 | import json
17 | import pandas as pd
18 | from io import StringIO
19 |
20 | _url = 'https://api.projectoxford.ai/vision/v1.0/ocr'
21 | _maxNumRetries = 10
22 |
23 | def main():
24 |
25 | # Get credential
26 | parser = configparser.ConfigParser()
27 | parser.read('config.ini')
28 | STORAGE_ACCOUNT_NAME = parser.get('credential', 'STORAGE_ACCOUNT_NAME_9')
29 | STORAGE_ACCOUNT_KEY = parser.get('credential', 'STORAGE_ACCOUNT_KEY_9')
30 | CONTAINER_NAME = parser.get('credential', 'CONTAINER_NAME_9')
31 | VISION_API_KEY = parser.get('credential', 'VISION_API_KEY_9') # need to use Agitare account
32 | CONTAINER_NAME_OCR = parser.get('credential', 'CONTAINER_NAME_OCR_9')
33 | CONTAINER_NAME_STRUCTUREDDATA = parser.get('credential', 'CONTAINER_NAME_STRUCTUREDDATA_9')
34 |
35 | # access to blob storage
36 | block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
37 | block_blob_service.set_container_acl(CONTAINER_NAME, public_access=PublicAccess.Container)
38 | generator = block_blob_service.list_blobs(CONTAINER_NAME)
39 |
40 | # empty dataframe
41 | df = pd.DataFrame({'Text' : [], 'Category' : [], 'ReceiptID' : []})
42 |
43 | # get label from file
44 | blob_text = block_blob_service.get_blob_to_text(CONTAINER_NAME, 'receipts_list-utf8.csv'); #print(blob_text.content)
45 | df_label = pd.DataFrame.from_csv(StringIO(blob_text.content), index_col=None, sep=','); #print(df_label.shape); print(df_label)
46 |
47 | # index
48 | index = 0
49 | for blob in generator:
50 | if index <= 2:
51 | print(blob.name)
52 | imageurl = "https://" + STORAGE_ACCOUNT_NAME + ".blob.core.windows.net/" + CONTAINER_NAME + "/" + blob.name; print(imageurl)
53 |
54 | # OCR parameters
55 | params = { 'language': 'en', 'detectOrientation ': 'true'}
56 |
57 | headers = dict()
58 | headers['Ocp-Apim-Subscription-Key'] = VISION_API_KEY
59 | headers['Content-Type'] = 'application/json'
60 |
61 | image_url = { 'url': imageurl } ;
62 | image_file = None
63 | result = processRequest( image_url, image_file, headers, params )
64 |
65 | if result is not None:
66 | #print(result)
67 | result_str = json.dumps(result); #print(result_str)
68 |
69 | # write result into blob
70 | ocrblobname = blob.name[:-3] + 'json'
71 | block_blob_service.create_blob_from_text(CONTAINER_NAME_OCR, ocrblobname, result_str)
72 | # extract text
73 | text = extractText(result); #print (text)
74 |
75 | # populate dataframe
76 | df.loc[index,'Text'] = text
77 | else:
78 | # populate dataframe
79 | df.loc[index,'Text'] = None
80 |
81 | df.loc[index,'Category'] = df_label.loc[index,'category']
82 | df.loc[index,'ReceiptID'] = blob.name
83 |
84 | else:
85 | break
86 | index = index + 1
87 |
88 | # write dataframe to blob
89 | print("-----------------------")
90 | df_str = df.to_csv(sep='\t', index=False);
91 |
92 | dfblobname = 'dataframe.tsv'
93 | block_blob_service.create_blob_from_text(CONTAINER_NAME_STRUCTUREDDATA, dfblobname, df_str)
94 |
95 | return
96 |
97 | def extractText(result):
98 | text = ""
99 | for region in result['regions']:
100 | for line in region['lines']:
101 | for word in line['words']:
102 | #print (word.get('text'))
103 | text = text + " " + word.get('text')
104 | return text
105 |
106 | def processRequest( image_url, image_file, headers, params ):
107 |
108 | """
109 | Ref: https://github.com/Microsoft/Cognitive-Vision-Python/blob/master/Jupyter%20Notebook/Computer%20Vision%20API%20Example.ipynb
110 | Helper function to process the request to Project Oxford
111 | Parameters:
112 | json: Used when processing images from its URL. See API Documentation
113 | data: Used when processing image read from disk. See API Documentation
114 | headers: Used to pass the key information and the data type request
115 | """
116 |
117 | retries = 0
118 | result = None
119 |
120 | while True:
121 |
122 | response = requests.request( 'post', _url, json = image_url, data = image_file, headers = headers, params = params )
123 |
124 | if response.status_code == 429:
125 |
126 | print( "Message: %s" % ( response.json()['message'] ) )
127 |
128 | if retries <= _maxNumRetries:
129 | time.sleep(1)
130 | retries += 1
131 | continue
132 | else:
133 | print( 'Error: failed after retrying!' )
134 | break
135 |
136 | elif response.status_code == 200 or response.status_code == 201:
137 |
138 | if 'content-length' in response.headers and int(response.headers['content-length']) == 0:
139 | result = None
140 | elif 'content-type' in response.headers and isinstance(response.headers['content-type'], str):
141 | if 'application/json' in response.headers['content-type'].lower():
142 | result = response.json() if response.content else None
143 | elif 'image' in response.headers['content-type'].lower():
144 | result = response.content
145 | else:
146 | print(response.json())
147 | print( "Error code: %d" % ( response.status_code ) );
148 | print( "Message: %s" % ( response.json()['message'] ) );
149 |
150 | break
151 |
152 | return result
153 |
154 | if __name__ == '__main__':
155 | main()
--------------------------------------------------------------------------------
/prep-data.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Sat Nov 5 10:35:35 2016
4 |
5 | @author: chyam
6 | Purpose: prepare sturctured-data for azure ml. load from blob, clean, i) write to blob ii) pass to a azure ml learner
7 | """
8 |
9 | from __future__ import print_function
10 | from azure.storage.blob import BlockBlobService
11 | from azure.storage.blob import ContentSettings
12 | import configparser
13 | import pandas as pd
14 | from io import StringIO
15 |
16 | def main():
17 |
18 | # Get credential
19 | parser = configparser.ConfigParser()
20 | parser.read('config.ini')
21 | STORAGE_ACCOUNT_NAME = parser.get('credential', 'STORAGE_ACCOUNT_NAME')
22 | STORAGE_ACCOUNT_KEY = parser.get('credential', 'STORAGE_ACCOUNT_KEY')
23 | CONTAINER_NAME_STRUCTUREDDATA = parser.get('credential', 'CONTAINER_NAME_STRUCTUREDDATA')
24 |
25 | # access to blob storage
26 | block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
27 |
28 | # load structured data from blob
29 | blob_text = block_blob_service.get_blob_to_text(CONTAINER_NAME_STRUCTUREDDATA, 'dataframe.tsv'); #print(blob_text.content)
30 | # clean df
31 | df = pd.DataFrame.from_csv(StringIO(blob_text.content), index_col=None, sep='\t'); print(df.shape)
32 | df_clean = df.dropna(); print(df_clean.shape)
33 |
34 | # write cleaned dataframe to blob
35 | print("-----------write cleaned dataframe to blob------------")
36 | df_clean_str = df_clean.to_csv(sep='\t', index=False);
37 |
38 | dfblobname = 'dataframe_cleaned.tsv'
39 | settings = ContentSettings(content_type='text/tab-separated-values')
40 | block_blob_service.create_blob_from_text(CONTAINER_NAME_STRUCTUREDDATA, dfblobname, df_clean_str, content_settings=settings)
41 |
42 | return
43 |
44 | if __name__ == '__main__':
45 | main()
--------------------------------------------------------------------------------
/prep-image-url.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Tue Nov 8 21:08:16 2016
4 |
5 | @author: chyam
6 | """
7 |
8 | from __future__ import print_function
9 | from azure.storage.blob import BlockBlobService
10 | from azure.storage.blob import PublicAccess
11 | import configparser
12 | import pandas as pd
13 | from io import StringIO
14 |
15 | def main():
16 |
17 | # Get credential
18 | parser = configparser.ConfigParser()
19 | parser.read('config.ini')
20 | STORAGE_ACCOUNT_NAME = parser.get('credential', 'STORAGE_ACCOUNT_NAME')
21 | STORAGE_ACCOUNT_KEY = parser.get('credential', 'STORAGE_ACCOUNT_KEY')
22 | CONTAINER_NAME = parser.get('credential', 'CONTAINER_NAME')
23 | CONTAINER_NAME_METADATA = parser.get('credential', 'CONTAINER_NAME_METADATA')
24 |
25 | # access to blob storage
26 | block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
27 | block_blob_service.set_container_acl(CONTAINER_NAME, public_access=PublicAccess.Container)
28 | generator = block_blob_service.list_blobs(CONTAINER_NAME)
29 |
30 | # empty dataframe
31 | df = pd.DataFrame({'Url' : [], 'Category' : []})
32 |
33 | # get label from file
34 | blob_text = block_blob_service.get_blob_to_text(CONTAINER_NAME_METADATA, 'receipt_list_labelled.csv'); #print(blob_text.content)
35 | df_label = pd.DataFrame.from_csv(StringIO(blob_text.content), index_col=None, sep=','); #print(df_label.shape); print(df_label)
36 |
37 | # index
38 | index = 0
39 | for blob in generator:
40 | print(blob.name)
41 | # populate dataframe
42 | df.loc[index,'Category'] = df_label.loc[index,'category']
43 | df.loc[index,'Url'] = imageurl = "https://" + STORAGE_ACCOUNT_NAME + ".blob.core.windows.net/" + CONTAINER_NAME + "/" + blob.name; print(imageurl)
44 | index = index + 1
45 |
46 | # write dataframe to blob
47 | print("-----------------------")
48 | df_str = df.to_csv(sep='\t', index=False);
49 |
50 | dfblobname = 'image-url.tsv'
51 | block_blob_service.create_blob_from_text(CONTAINER_NAME_METADATA, dfblobname, df_str)
52 |
53 | return
54 |
55 | if __name__ == '__main__':
56 | main()
--------------------------------------------------------------------------------
/redistribute-data.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Tue Nov 8 04:41:15 2016
4 |
5 | @author: chyam
6 | purpose: data re-labelling to reduce grouping.
7 | """
8 |
9 | from __future__ import print_function
10 | from azure.storage.blob import BlockBlobService
11 | from azure.storage.blob import ContentSettings
12 | import configparser
13 | import pandas as pd
14 | from io import StringIO
15 |
16 | def main():
17 |
18 | # Get credential
19 | parser = configparser.ConfigParser()
20 | parser.read('config.ini')
21 | STORAGE_ACCOUNT_NAME = parser.get('credential', 'STORAGE_ACCOUNT_NAME')
22 | STORAGE_ACCOUNT_KEY = parser.get('credential', 'STORAGE_ACCOUNT_KEY')
23 | CONTAINER_NAME_METADATA = parser.get('credential', 'CONTAINER_NAME_METADATA')
24 |
25 | # access to blob storage
26 | block_blob_service = BlockBlobService(account_name=STORAGE_ACCOUNT_NAME, account_key=STORAGE_ACCOUNT_KEY)
27 |
28 | # load structured data from blob
29 | blob_text = block_blob_service.get_blob_to_text(CONTAINER_NAME_METADATA, 'image-url.tsv'); #print(blob_text.content)
30 | df = pd.DataFrame.from_csv(StringIO(blob_text.content), index_col=None, sep='\t'); print(df.shape)
31 |
32 | # Frequency
33 | df_crosstab = pd.crosstab(index=df["Category"], columns="count")
34 | print(df_crosstab)
35 |
36 | print(df.shape)
37 | df_sub = pd.concat([df.loc[df['Category'] == 'daily snack'],
38 | df.loc[df['Category'] == 'groceries'],
39 | df.loc[df['Category'] == 'dining out'],
40 | df.loc[df['Category'] == 'clothes and accessories'],
41 | df.loc[df['Category'] == 'fuel'],
42 | df.loc[df['Category'] == 'entertinement']])
43 | print(df_sub.shape)
44 | print(df_sub.Category.unique())
45 |
46 | # write cleaned dataframe to blob
47 | print("-----------write cleaned dataframe to blob------------")
48 | df_sub_str = df_sub.to_csv(sep='\t', index=False);
49 |
50 | #dfblobname = 'dataframe_6_classes.tsv'
51 | dfblobname = 'image-url-6-classes.tsv'
52 | settings = ContentSettings(content_type='text/tab-separated-values')
53 | block_blob_service.create_blob_from_text(CONTAINER_NAME_METADATA, dfblobname, df_sub_str, content_settings=settings)
54 |
55 | return
56 |
57 | if __name__ == '__main__':
58 | main()
--------------------------------------------------------------------------------