├── LICENSE
├── README.md
├── android
├── app
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── io
│ │ │ └── flutter
│ │ │ └── plugins
│ │ │ └── GeneratedPluginRegistrant.java
│ │ ├── kotlin
│ │ └── waynelu
│ │ │ └── flutterocr
│ │ │ └── MainActivity.kt
│ │ └── res
│ │ ├── drawable
│ │ └── launch_background.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ └── values
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
├── flutter_ocr.iml
├── flutter_ocr_android.iml
├── fonts
└── Imgcrop.ttf
├── images
├── bottomLeft.png
├── bottomRight.png
├── demo1.jpg
├── demo2.jpg
├── demo3.jpg
├── demo4.jpg
├── topLeft.png
└── topRight.png
├── ios
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ ├── Generated.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ └── contents.xcworkspacedata
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── GeneratedPluginRegistrant.h
│ ├── GeneratedPluginRegistrant.m
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── image_page.dart
├── imgcrop_icons.dart
├── main.dart
├── result_page.dart
├── rotatescale.dart
└── text_list.dart
└── pubspec.yaml
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter_ocr
2 |
3 | flutter_ocr是用flutter开发的使用百度api进行文字识别的拍照取字软件。
4 |
5 | 包含了拍照,旋转,放大,拖拽来选取合适的大小和角度来截取要识别的图片内容。
6 |
7 |
8 |
9 |
10 |
11 | ## Getting Started
12 |
13 | For help getting started with Flutter, view our online
14 | [documentation](https://flutter.io/).
15 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 27
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "waynelu.flutterocr"
42 | minSdkVersion 21
43 | targetSdkVersion 27
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.debug
54 | }
55 | }
56 | }
57 |
58 | flutter {
59 | source '../..'
60 | }
61 |
62 | dependencies {
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
64 | testImplementation 'junit:junit:4.12'
65 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
67 | }
68 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
15 |
19 |
26 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java:
--------------------------------------------------------------------------------
1 | package io.flutter.plugins;
2 |
3 | import io.flutter.plugin.common.PluginRegistry;
4 | import io.flutter.plugins.camera.CameraPlugin;
5 | import io.flutter.plugins.imagepicker.ImagePickerPlugin;
6 | import io.flutter.plugins.pathprovider.PathProviderPlugin;
7 | import io.flutter.plugins.videoplayer.VideoPlayerPlugin;
8 |
9 | /**
10 | * Generated file. Do not edit.
11 | */
12 | public final class GeneratedPluginRegistrant {
13 | public static void registerWith(PluginRegistry registry) {
14 | if (alreadyRegisteredWith(registry)) {
15 | return;
16 | }
17 | CameraPlugin.registerWith(registry.registrarFor("io.flutter.plugins.camera.CameraPlugin"));
18 | ImagePickerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.imagepicker.ImagePickerPlugin"));
19 | PathProviderPlugin.registerWith(registry.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"));
20 | VideoPlayerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.videoplayer.VideoPlayerPlugin"));
21 | }
22 |
23 | private static boolean alreadyRegisteredWith(PluginRegistry registry) {
24 | final String key = GeneratedPluginRegistrant.class.getCanonicalName();
25 | if (registry.hasPlugin(key)) {
26 | return true;
27 | }
28 | registry.registrarFor(key);
29 | return false;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/waynelu/flutterocr/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package waynelu.flutterocr
2 |
3 | import android.os.Bundle
4 |
5 | import io.flutter.app.FlutterActivity
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | GeneratedPluginRegistrant.registerWith(this)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.2.71'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.2.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/local.properties:
--------------------------------------------------------------------------------
1 | sdk.dir=/Users/waynelu/Library/Android/sdk
2 | flutter.sdk=/Users/waynelu/flutter
3 | flutter.versionName=1.0.0
4 | flutter.versionCode=1
5 | flutter.buildMode=debug
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/flutter_ocr.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/flutter_ocr_android.iml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/fonts/Imgcrop.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/fonts/Imgcrop.ttf
--------------------------------------------------------------------------------
/images/bottomLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/bottomLeft.png
--------------------------------------------------------------------------------
/images/bottomRight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/bottomRight.png
--------------------------------------------------------------------------------
/images/demo1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/demo1.jpg
--------------------------------------------------------------------------------
/images/demo2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/demo2.jpg
--------------------------------------------------------------------------------
/images/demo3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/demo3.jpg
--------------------------------------------------------------------------------
/images/demo4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/demo4.jpg
--------------------------------------------------------------------------------
/images/topLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/topLeft.png
--------------------------------------------------------------------------------
/images/topRight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/images/topRight.png
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Generated.xcconfig:
--------------------------------------------------------------------------------
1 | // This is a generated file; do not edit or check into version control.
2 | FLUTTER_ROOT=/Users/waynelu/flutter
3 | FLUTTER_APPLICATION_PATH=/Users/waynelu/q/flutter_ocr
4 | FLUTTER_TARGET=lib/main.dart
5 | FLUTTER_BUILD_MODE=debug
6 | FLUTTER_BUILD_DIR=build
7 | SYMROOT=${SOURCE_ROOT}/../build/ios
8 | FLUTTER_FRAMEWORK_DIR=/Users/waynelu/flutter/bin/cache/artifacts/engine/ios
9 | FLUTTER_BUILD_NAME=1.0.0
10 | FLUTTER_BUILD_NUMBER=1
11 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
16 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
17 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
18 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
19 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
20 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
21 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXCopyFilesBuildPhase section */
25 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
26 | isa = PBXCopyFilesBuildPhase;
27 | buildActionMask = 2147483647;
28 | dstPath = "";
29 | dstSubfolderSpec = 10;
30 | files = (
31 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
32 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
33 | );
34 | name = "Embed Frameworks";
35 | runOnlyForDeploymentPostprocessing = 0;
36 | };
37 | /* End PBXCopyFilesBuildPhase section */
38 |
39 | /* Begin PBXFileReference section */
40 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
41 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
42 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
43 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
44 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
45 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
46 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
47 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
48 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
49 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
50 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
51 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
55 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | /* End PBXFileReference section */
57 |
58 | /* Begin PBXFrameworksBuildPhase section */
59 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
64 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | 9740EEB11CF90186004384FC /* Flutter */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
75 | 3B80C3931E831B6300D905FE /* App.framework */,
76 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
77 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
78 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
79 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
80 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
81 | );
82 | name = Flutter;
83 | sourceTree = "";
84 | };
85 | 97C146E51CF9000F007C117D = {
86 | isa = PBXGroup;
87 | children = (
88 | 9740EEB11CF90186004384FC /* Flutter */,
89 | 97C146F01CF9000F007C117D /* Runner */,
90 | 97C146EF1CF9000F007C117D /* Products */,
91 | );
92 | sourceTree = "";
93 | };
94 | 97C146EF1CF9000F007C117D /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 97C146EE1CF9000F007C117D /* Runner.app */,
98 | );
99 | name = Products;
100 | sourceTree = "";
101 | };
102 | 97C146F01CF9000F007C117D /* Runner */ = {
103 | isa = PBXGroup;
104 | children = (
105 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
106 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
107 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
108 | 97C147021CF9000F007C117D /* Info.plist */,
109 | 97C146F11CF9000F007C117D /* Supporting Files */,
110 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
111 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
112 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
113 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
114 | );
115 | path = Runner;
116 | sourceTree = "";
117 | };
118 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
119 | isa = PBXGroup;
120 | children = (
121 | );
122 | name = "Supporting Files";
123 | sourceTree = "";
124 | };
125 | /* End PBXGroup section */
126 |
127 | /* Begin PBXNativeTarget section */
128 | 97C146ED1CF9000F007C117D /* Runner */ = {
129 | isa = PBXNativeTarget;
130 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
131 | buildPhases = (
132 | 9740EEB61CF901F6004384FC /* Run Script */,
133 | 97C146EA1CF9000F007C117D /* Sources */,
134 | 97C146EB1CF9000F007C117D /* Frameworks */,
135 | 97C146EC1CF9000F007C117D /* Resources */,
136 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
137 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
138 | );
139 | buildRules = (
140 | );
141 | dependencies = (
142 | );
143 | name = Runner;
144 | productName = Runner;
145 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
146 | productType = "com.apple.product-type.application";
147 | };
148 | /* End PBXNativeTarget section */
149 |
150 | /* Begin PBXProject section */
151 | 97C146E61CF9000F007C117D /* Project object */ = {
152 | isa = PBXProject;
153 | attributes = {
154 | LastUpgradeCheck = 0910;
155 | ORGANIZATIONNAME = "The Chromium Authors";
156 | TargetAttributes = {
157 | 97C146ED1CF9000F007C117D = {
158 | CreatedOnToolsVersion = 7.3.1;
159 | LastSwiftMigration = 0910;
160 | };
161 | };
162 | };
163 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
164 | compatibilityVersion = "Xcode 3.2";
165 | developmentRegion = English;
166 | hasScannedForEncodings = 0;
167 | knownRegions = (
168 | en,
169 | Base,
170 | );
171 | mainGroup = 97C146E51CF9000F007C117D;
172 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
173 | projectDirPath = "";
174 | projectRoot = "";
175 | targets = (
176 | 97C146ED1CF9000F007C117D /* Runner */,
177 | );
178 | };
179 | /* End PBXProject section */
180 |
181 | /* Begin PBXResourcesBuildPhase section */
182 | 97C146EC1CF9000F007C117D /* Resources */ = {
183 | isa = PBXResourcesBuildPhase;
184 | buildActionMask = 2147483647;
185 | files = (
186 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
187 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
188 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
189 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
190 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
191 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
192 | );
193 | runOnlyForDeploymentPostprocessing = 0;
194 | };
195 | /* End PBXResourcesBuildPhase section */
196 |
197 | /* Begin PBXShellScriptBuildPhase section */
198 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
199 | isa = PBXShellScriptBuildPhase;
200 | buildActionMask = 2147483647;
201 | files = (
202 | );
203 | inputPaths = (
204 | );
205 | name = "Thin Binary";
206 | outputPaths = (
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | shellPath = /bin/sh;
210 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
211 | };
212 | 9740EEB61CF901F6004384FC /* Run Script */ = {
213 | isa = PBXShellScriptBuildPhase;
214 | buildActionMask = 2147483647;
215 | files = (
216 | );
217 | inputPaths = (
218 | );
219 | name = "Run Script";
220 | outputPaths = (
221 | );
222 | runOnlyForDeploymentPostprocessing = 0;
223 | shellPath = /bin/sh;
224 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
225 | };
226 | /* End PBXShellScriptBuildPhase section */
227 |
228 | /* Begin PBXSourcesBuildPhase section */
229 | 97C146EA1CF9000F007C117D /* Sources */ = {
230 | isa = PBXSourcesBuildPhase;
231 | buildActionMask = 2147483647;
232 | files = (
233 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
234 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
235 | );
236 | runOnlyForDeploymentPostprocessing = 0;
237 | };
238 | /* End PBXSourcesBuildPhase section */
239 |
240 | /* Begin PBXVariantGroup section */
241 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
242 | isa = PBXVariantGroup;
243 | children = (
244 | 97C146FB1CF9000F007C117D /* Base */,
245 | );
246 | name = Main.storyboard;
247 | sourceTree = "";
248 | };
249 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
250 | isa = PBXVariantGroup;
251 | children = (
252 | 97C147001CF9000F007C117D /* Base */,
253 | );
254 | name = LaunchScreen.storyboard;
255 | sourceTree = "";
256 | };
257 | /* End PBXVariantGroup section */
258 |
259 | /* Begin XCBuildConfiguration section */
260 | 97C147031CF9000F007C117D /* Debug */ = {
261 | isa = XCBuildConfiguration;
262 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
263 | buildSettings = {
264 | ALWAYS_SEARCH_USER_PATHS = NO;
265 | CLANG_ANALYZER_NONNULL = YES;
266 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
267 | CLANG_CXX_LIBRARY = "libc++";
268 | CLANG_ENABLE_MODULES = YES;
269 | CLANG_ENABLE_OBJC_ARC = YES;
270 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
271 | CLANG_WARN_BOOL_CONVERSION = YES;
272 | CLANG_WARN_COMMA = YES;
273 | CLANG_WARN_CONSTANT_CONVERSION = YES;
274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
275 | CLANG_WARN_EMPTY_BODY = YES;
276 | CLANG_WARN_ENUM_CONVERSION = YES;
277 | CLANG_WARN_INFINITE_RECURSION = YES;
278 | CLANG_WARN_INT_CONVERSION = YES;
279 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
283 | CLANG_WARN_STRICT_PROTOTYPES = YES;
284 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
285 | CLANG_WARN_UNREACHABLE_CODE = YES;
286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
288 | COPY_PHASE_STRIP = NO;
289 | DEBUG_INFORMATION_FORMAT = dwarf;
290 | ENABLE_STRICT_OBJC_MSGSEND = YES;
291 | ENABLE_TESTABILITY = YES;
292 | GCC_C_LANGUAGE_STANDARD = gnu99;
293 | GCC_DYNAMIC_NO_PIC = NO;
294 | GCC_NO_COMMON_BLOCKS = YES;
295 | GCC_OPTIMIZATION_LEVEL = 0;
296 | GCC_PREPROCESSOR_DEFINITIONS = (
297 | "DEBUG=1",
298 | "$(inherited)",
299 | );
300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
302 | GCC_WARN_UNDECLARED_SELECTOR = YES;
303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
304 | GCC_WARN_UNUSED_FUNCTION = YES;
305 | GCC_WARN_UNUSED_VARIABLE = YES;
306 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
307 | MTL_ENABLE_DEBUG_INFO = YES;
308 | ONLY_ACTIVE_ARCH = YES;
309 | SDKROOT = iphoneos;
310 | TARGETED_DEVICE_FAMILY = "1,2";
311 | };
312 | name = Debug;
313 | };
314 | 97C147041CF9000F007C117D /* Release */ = {
315 | isa = XCBuildConfiguration;
316 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
317 | buildSettings = {
318 | ALWAYS_SEARCH_USER_PATHS = NO;
319 | CLANG_ANALYZER_NONNULL = YES;
320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
321 | CLANG_CXX_LIBRARY = "libc++";
322 | CLANG_ENABLE_MODULES = YES;
323 | CLANG_ENABLE_OBJC_ARC = YES;
324 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
325 | CLANG_WARN_BOOL_CONVERSION = YES;
326 | CLANG_WARN_COMMA = YES;
327 | CLANG_WARN_CONSTANT_CONVERSION = YES;
328 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
329 | CLANG_WARN_EMPTY_BODY = YES;
330 | CLANG_WARN_ENUM_CONVERSION = YES;
331 | CLANG_WARN_INFINITE_RECURSION = YES;
332 | CLANG_WARN_INT_CONVERSION = YES;
333 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
337 | CLANG_WARN_STRICT_PROTOTYPES = YES;
338 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
339 | CLANG_WARN_UNREACHABLE_CODE = YES;
340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
342 | COPY_PHASE_STRIP = NO;
343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
344 | ENABLE_NS_ASSERTIONS = NO;
345 | ENABLE_STRICT_OBJC_MSGSEND = YES;
346 | GCC_C_LANGUAGE_STANDARD = gnu99;
347 | GCC_NO_COMMON_BLOCKS = YES;
348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
350 | GCC_WARN_UNDECLARED_SELECTOR = YES;
351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
352 | GCC_WARN_UNUSED_FUNCTION = YES;
353 | GCC_WARN_UNUSED_VARIABLE = YES;
354 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
355 | MTL_ENABLE_DEBUG_INFO = NO;
356 | SDKROOT = iphoneos;
357 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
358 | TARGETED_DEVICE_FAMILY = "1,2";
359 | VALIDATE_PRODUCT = YES;
360 | };
361 | name = Release;
362 | };
363 | 97C147061CF9000F007C117D /* Debug */ = {
364 | isa = XCBuildConfiguration;
365 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
366 | buildSettings = {
367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
368 | CLANG_ENABLE_MODULES = YES;
369 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
370 | ENABLE_BITCODE = NO;
371 | FRAMEWORK_SEARCH_PATHS = (
372 | "$(inherited)",
373 | "$(PROJECT_DIR)/Flutter",
374 | );
375 | INFOPLIST_FILE = Runner/Info.plist;
376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
377 | LIBRARY_SEARCH_PATHS = (
378 | "$(inherited)",
379 | "$(PROJECT_DIR)/Flutter",
380 | );
381 | PRODUCT_BUNDLE_IDENTIFIER = waynelu.flutterOcr;
382 | PRODUCT_NAME = "$(TARGET_NAME)";
383 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
384 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
385 | SWIFT_SWIFT3_OBJC_INFERENCE = On;
386 | SWIFT_VERSION = 4.0;
387 | VERSIONING_SYSTEM = "apple-generic";
388 | };
389 | name = Debug;
390 | };
391 | 97C147071CF9000F007C117D /* Release */ = {
392 | isa = XCBuildConfiguration;
393 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
394 | buildSettings = {
395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
396 | CLANG_ENABLE_MODULES = YES;
397 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
398 | ENABLE_BITCODE = NO;
399 | FRAMEWORK_SEARCH_PATHS = (
400 | "$(inherited)",
401 | "$(PROJECT_DIR)/Flutter",
402 | );
403 | INFOPLIST_FILE = Runner/Info.plist;
404 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
405 | LIBRARY_SEARCH_PATHS = (
406 | "$(inherited)",
407 | "$(PROJECT_DIR)/Flutter",
408 | );
409 | PRODUCT_BUNDLE_IDENTIFIER = waynelu.flutterOcr;
410 | PRODUCT_NAME = "$(TARGET_NAME)";
411 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
412 | SWIFT_SWIFT3_OBJC_INFERENCE = On;
413 | SWIFT_VERSION = 4.0;
414 | VERSIONING_SYSTEM = "apple-generic";
415 | };
416 | name = Release;
417 | };
418 | /* End XCBuildConfiguration section */
419 |
420 | /* Begin XCConfigurationList section */
421 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
422 | isa = XCConfigurationList;
423 | buildConfigurations = (
424 | 97C147031CF9000F007C117D /* Debug */,
425 | 97C147041CF9000F007C117D /* Release */,
426 | );
427 | defaultConfigurationIsVisible = 0;
428 | defaultConfigurationName = Release;
429 | };
430 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
431 | isa = XCConfigurationList;
432 | buildConfigurations = (
433 | 97C147061CF9000F007C117D /* Debug */,
434 | 97C147071CF9000F007C117D /* Release */,
435 | );
436 | defaultConfigurationIsVisible = 0;
437 | defaultConfigurationName = Release;
438 | };
439 | /* End XCConfigurationList section */
440 | };
441 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
442 | }
443 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyongfugx/flutter_ocr/0063a2697e691253911f97fc291f4873fda97c98/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/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 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.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 |
--------------------------------------------------------------------------------
/ios/Runner/GeneratedPluginRegistrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #ifndef GeneratedPluginRegistrant_h
6 | #define GeneratedPluginRegistrant_h
7 |
8 | #import
9 |
10 | @interface GeneratedPluginRegistrant : NSObject
11 | + (void)registerWithRegistry:(NSObject*)registry;
12 | @end
13 |
14 | #endif /* GeneratedPluginRegistrant_h */
15 |
--------------------------------------------------------------------------------
/ios/Runner/GeneratedPluginRegistrant.m:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #import "GeneratedPluginRegistrant.h"
6 | #import
7 | #import
8 | #import
9 | #import
10 |
11 | @implementation GeneratedPluginRegistrant
12 |
13 | + (void)registerWithRegistry:(NSObject*)registry {
14 | [CameraPlugin registerWithRegistrar:[registry registrarForPlugin:@"CameraPlugin"]];
15 | [FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]];
16 | [FLTPathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTPathProviderPlugin"]];
17 | [FLTVideoPlayerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTVideoPlayerPlugin"]];
18 | }
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_ocr
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/lib/image_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 |
3 | import 'package:flutter/gestures.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/cupertino.dart';
6 | import 'package:flutter/rendering.dart';
7 | import 'dart:io';
8 | import 'package:dio/dio.dart';
9 | import 'dart:math' as math;
10 | import 'dart:async';
11 | import 'dart:convert';
12 | import 'dart:isolate';
13 | import 'dart:ui' as ui;
14 | import 'rotatescale.dart';
15 | import 'imgcrop_icons.dart';
16 | import 'result_page.dart';
17 | import 'package:image/image.dart' as ImageUtil;
18 | class CropPage extends StatefulWidget {
19 | CropPage({Key key, this.title, this.image, this.imageInfo}) : super(key: key);
20 | final String title;
21 | final ui.Image image;
22 | ImageInfo imageInfo;
23 | @override
24 | _CropPageState createState() => new _CropPageState();
25 | }
26 |
27 | class _CropPageState extends State with SingleTickerProviderStateMixin{
28 | GlobalKey globalKey = new GlobalKey();
29 | ui.Image corpImg;
30 | String maskDirection = "center";
31 | double opacity = 0.5;
32 | double maskTop = 60.0;
33 | double maskLeft = 40.0;
34 | double maskWidth = 0.0;
35 | double maskHeight = 0.0;
36 | double dragStartX = 0.0;
37 | double dragStartY = 0.0;
38 | double imgDragStartX = 0.0;
39 | double imgDragStartY = 0.0;
40 | double imgWidth = 0.0;
41 | double imgHeight = 0.0;
42 | double oldScale = 1.0;
43 | double _scale = 1.0;
44 | double oldRotate = 0.0;
45 | String baiduApi = "https://aip.baidubce.com/oauth/2.0/token?";
46 | String baiduRestApi = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?";
47 | String baiduGrantType = "client_credentials";
48 | String baiduClientId = "";//百度ocr api的 clientId,请自行申请
49 | String baiduClientSecret = "";//百度ocr api的 Secret
50 |
51 | double rotate = 0.0;
52 | Offset topLeft = new Offset(40.0, 60.0);
53 | Matrix4 matrix = new Matrix4.identity();
54 | GlobalKey imgKey = new GlobalKey();
55 | AnimationController _controller;//扫描动画
56 | @override
57 | void initState() {
58 | super.initState();
59 | _controller = new AnimationController(
60 | duration: new Duration(seconds: 3),
61 | vsync: this
62 | )
63 | ..addListener(() {
64 | this.setState(() {});
65 | });
66 |
67 | }
68 |
69 | static decodePng(SendPort sendPort) async {
70 | var port = new ReceivePort();
71 | sendPort.send(port.sendPort);
72 | // 监听消息
73 | await for (var msg in port) {
74 | var data = msg[0];
75 | ImageUtil.Image image = ImageUtil.decodePng(data);
76 | SendPort replyTo = msg[1];
77 | replyTo.send(image);
78 | port.close();
79 | }
80 | }
81 | /// 对某个port发送消息,并接收结果
82 | Future sendReceive(SendPort port, msg) {
83 | ReceivePort response = new ReceivePort();
84 | port.send([msg, response.sendPort]);
85 | return response.first;
86 | }
87 |
88 | static encodePng(SendPort sendPort) async {
89 | var port = new ReceivePort();
90 | sendPort.send(port.sendPort);
91 | // 监听消息
92 | await for (var msg in port) {
93 | var data = msg[0];
94 | List byteList = ImageUtil.encodePng(data);
95 | SendPort replyTo = msg[1];
96 | replyTo.send(byteList);
97 | port.close();
98 | }
99 | // return new Future(() => ImageUtil.encodePng(image));
100 | }
101 |
102 | Future copyCrop(ImageUtil.Image image,int corpX, int corpY, int corpWidth, int corpHeight) async {
103 | return new Future(() => ImageUtil.copyCrop(image, corpX, corpY, corpWidth, corpHeight));
104 | }
105 |
106 | Future _capturePng() async {
107 | RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
108 | double pixelRatio = 1.5;
109 | ui.Image image = await boundary.toImage(pixelRatio:pixelRatio);
110 | ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
111 | Uint8List pngBytes = byteData.buffer.asUint8List();
112 | var receivePort = new ReceivePort();
113 | await Isolate.spawn(decodePng, receivePort.sendPort);
114 | var sendPort = await receivePort.first;
115 | ImageUtil.Image uImage = await sendReceive(sendPort, pngBytes);
116 | int corpX = (maskLeft*pixelRatio).toInt();
117 | int corpY = (maskTop*pixelRatio).toInt();
118 | int corpWidth = (maskWidth*pixelRatio).toInt();
119 | int corpHeight = (maskHeight*pixelRatio).toInt();
120 | print(uImage.width.toString()+" "+uImage.height.toString()+" "+corpX.toString()+" " +corpY.toString()+" "+corpWidth.toString()+" "+ corpHeight.toString());
121 | var nImage = await copyCrop(uImage, corpX, corpY, corpWidth, corpHeight);
122 | var receivePort1 = new ReceivePort();
123 | await Isolate.spawn(encodePng, receivePort1.sendPort);
124 | var sendPort1 = await receivePort1.first;
125 | List byteList = await sendReceive(sendPort1, nImage);
126 |
127 | String base64Image = base64Encode(byteList);//base 64
128 | var codec = await ui.instantiateImageCodec(byteList);
129 | var frame = await codec.getNextFrame();
130 |
131 | Dio dio = new Dio();
132 | String tokenUrl = baiduApi+"grant_type="+baiduGrantType+"&client_id="+baiduClientId+"&client_secret="+baiduClientSecret;
133 |
134 | Response response=await dio.post(tokenUrl);
135 | String accessToken = response.data['access_token'].toString();
136 | String ocrUrl = baiduRestApi+"access_token="+accessToken;
137 | Response res = await dio.post(ocrUrl,data:{"image":base64Image}, options: new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")));
138 | int wordsNum = int.parse(res.data["words_result_num"].toString());
139 | print(res.data.toString());
140 | List ocrContent = new List();
141 | if(wordsNum>0){
142 | var array = res.data["words_result"];
143 | for(var ar in array){
144 | ocrContent.add(ar["words"].toString());
145 | // ocrContent += ar["words"].toString()+"\n";
146 | print(ar["words"].toString());
147 | }
148 |
149 | }
150 | //if(res.data["words_result_num"])
151 | //重置
152 | _controller.reset();
153 | _controller.stop();
154 |
155 | Navigator.push(
156 | context,
157 | new MaterialPageRoute(
158 | builder: (context) => new ResultPage(
159 | title: 'crop',
160 | ocrContent: ocrContent,
161 | image: frame.image)));
162 |
163 | }
164 | void doCapturePng() async {
165 | _controller.repeat();
166 | _capturePng();
167 |
168 | }
169 | void onPanStart(DragStartDetails dragInfo) {
170 | dragStartX = dragInfo.globalPosition.dx;
171 | dragStartY = dragInfo.globalPosition.dy;
172 | }
173 | void onMaskPanStart(DragStartDetails dragInfo) {
174 | dragStartX = dragInfo.globalPosition.dx;
175 | dragStartY = dragInfo.globalPosition.dy;
176 | double margin = 20.0;
177 | //点击位置离跟左边点在10以内
178 | if((dragStartX -maskLeft).abs() < margin && dragStartY>(maskTop+margin) && dragStartY<(maskTop+maskHeight-margin)){
179 | maskDirection = "left";
180 | }
181 | else if((dragStartY -maskTop).abs() < margin && dragStartX>(maskLeft+margin) && dragStartX<(maskLeft+maskWidth-margin)){
182 | maskDirection = "top";
183 | }
184 | else if((dragStartX -(maskLeft+maskWidth)).abs() < margin && dragStartY>(maskTop+margin) && dragStartY<(maskTop+maskHeight-margin)){
185 | maskDirection = "right";
186 | }
187 | else if((dragStartY -(maskTop+maskHeight)).abs() < margin && dragStartX>(maskLeft+margin) && dragStartX<(maskLeft+maskWidth-margin)){
188 | maskDirection = "bottom";
189 | }
190 | else{
191 | maskDirection = "center";
192 | }
193 | //print(maskDirection+" " +dragStartX.toString()+" "+maskLeft.toString()+" "+(dragStartX -maskLeft).abs().toString());
194 |
195 | }
196 | void onPanEnd(DragEndDetails details) {
197 | dragStartX = 0.0;
198 | dragStartY = 0.0;
199 | }
200 |
201 | void onScaleStart(ScaleRotateStartDetails details) {
202 | imgDragStartX = details.focalPoint.dx;
203 | imgDragStartY = details.focalPoint.dy;
204 | rotate = 0.0;
205 | }
206 |
207 | void onScaleUpdate(ScaleRotateUpdateDetails details) {
208 | double degrees = details.rotation * (180 / math.pi);
209 | if (details.scale == 1 && details.rotation == 0) {
210 | double moveX = (details.focalPoint.dx - imgDragStartX);
211 | double moveY = (details.focalPoint.dy - imgDragStartY);
212 | imgDragStartX = imgDragStartX + moveX;
213 | imgDragStartY = imgDragStartY + moveY;
214 | double dx = (topLeft.dx + moveX);
215 | double dy = (topLeft.dy + moveY);
216 | // print("topLeft:"+topLeft.dx.toString()+" "+topLeft.dy.toString());
217 | //print("dragInfo.globalPosition.dx:"+details.focalPoint.dx.toString()+" dragInfo.globalPosition.dy:"+details.focalPoint.dy.toString());
218 | //print("moveX:"+moveX.toString()+" moveY:"+moveY.toString()+" this.context.size.width:"+this.context.size.width.toString()+" dx:"+dx.toString());
219 | // if(dx <= (10-this.context.size.width)){//不能往左拖动太厉害
220 | // dx = 10-this.context.size.width;
221 | // }
222 | // if(dx >= this.context.size.width-10){//不能往右拖动太厉害
223 | // dx = this.context.size.width-10;
224 | // }
225 | //
226 | // double imageHeight = imageInfo.image.height*((MediaQuery.of(this.context).size.width-20)/imageInfo.image.width);
227 | //
228 | // if(dy <= (10-imageHeight)){//不能太网上拖
229 | // dy = 10-imageHeight;
230 | // }
231 | // if(dy >= this.context.size.height+imageHeight-10){//不能往下拖动太厉害
232 | // dy = this.context.size.height+imageHeight-10;
233 | // }
234 |
235 | Offset offset = new Offset(dx, dy);
236 | //print("offset:"+offset.dx.toString()+" "+offset.dy.toString());
237 | setState(() {
238 | topLeft = offset;
239 | });
240 | } else {
241 | doRotateAndZoom(details.rotation, details.scale);
242 | }
243 | }
244 |
245 | void doRotateAndZoom(double rt, double scale) {
246 | rotate = rt;
247 | var matrix1 = new Matrix4.identity()..rotateZ(oldRotate + rotate);
248 | var diffScale = scale - _scale;
249 | oldScale = oldScale + diffScale;
250 | // if(diffScale>0.05 || diffScale<0.05){
251 | matrix1 = new Matrix4.identity()
252 | ..rotateZ(oldRotate + rotate)
253 | ..scale(oldScale);
254 | //}
255 | setState(() {
256 | matrix = matrix1;
257 | });
258 | _scale = scale;
259 | }
260 |
261 | void onScaleEnd(ScaleRotateEndDetails details) {
262 | imgDragStartX = 0.0;
263 | imgDragStartY = 0.0;
264 | oldRotate = oldRotate + rotate;
265 | rotate = 0.0;
266 | _scale = 1.0;
267 | }
268 |
269 | void onPanUpdate(String btn, DragUpdateDetails dragInfo) {
270 | //重新计算move
271 | //重新计算move
272 | double moveX = (dragInfo.globalPosition.dx - dragStartX);
273 | double moveY = (dragInfo.globalPosition.dy - dragStartY);
274 |
275 | dragStartX = dragStartX + moveX;
276 | dragStartY = dragStartY + moveY;
277 |
278 | double _maskHeight = maskHeight;
279 | double _maskWidth = maskWidth;
280 | double _maskTop = maskTop;
281 | double _maskLeft = maskLeft;
282 | //topleft,都变化了
283 | if (btn == "topleft") {
284 | _maskHeight = maskHeight - moveY;
285 | _maskWidth = maskWidth - moveX;
286 | _maskTop = maskTop + moveY;
287 | _maskLeft = maskLeft + moveX;
288 | }
289 |
290 | //topright,left不变
291 | if (btn == "topright") {
292 | _maskWidth = maskWidth + moveX;
293 | _maskHeight = maskHeight - moveY;
294 | _maskTop = maskTop + moveY;
295 | }
296 |
297 | //bottomLeft
298 | if (btn == "bottomleft") {
299 | _maskWidth = maskWidth - moveX;
300 | _maskLeft = maskLeft + moveX;
301 | _maskHeight = maskHeight + moveY;
302 | //_maskTop = maskTop+ moveY;
303 | }
304 |
305 | //bottomRight
306 | if (btn == "bottomright") {
307 | _maskWidth = maskWidth + moveX;
308 | _maskHeight = maskHeight + moveY;
309 | }
310 | if (btn == "left") {
311 | _maskWidth = maskWidth - moveX;
312 | _maskLeft = maskLeft + moveX;
313 | }
314 |
315 | if (btn == "top") {
316 | _maskHeight = maskHeight - moveY;
317 | _maskTop = maskTop + moveY;
318 | }
319 | if (btn == "bottom") {
320 | _maskHeight = maskHeight + moveY;
321 | }
322 | if (btn == "right") {
323 | _maskWidth = maskWidth + moveX;
324 | }
325 |
326 | //center
327 | if (btn == "center") {
328 | _maskLeft = maskLeft + moveX;
329 | _maskTop = maskTop + moveY;
330 | }
331 |
332 | //debugPrint("undate x:"+dragInfo.globalPosition.dx.toString()+" y:"+dragInfo.globalPosition.dy.toString()+" move:"+moveX.toString()+" maskWidth:" +maskWidth.toString());
333 | setState(() {
334 | maskWidth = _maskWidth;
335 | maskHeight = _maskHeight;
336 | maskTop = _maskTop;
337 | maskLeft = _maskLeft;
338 | });
339 | }
340 |
341 | Widget buildLoading() {
342 | return new Center(
343 | child: new Text(
344 | "Loading",
345 | style: new TextStyle(color: Colors.white),
346 | ));
347 | }
348 | @override
349 | void didChangeDependencies() {
350 | super.didChangeDependencies();
351 | var size = MediaQuery.of(context).size;
352 | //手机宽高比
353 | var devW = size.width-40*2;
354 | var devH = size.height-2*60;
355 | var devWh = devW/devH;
356 | var imgWh = widget.imageInfo.image.width/widget.imageInfo.image.height;
357 | if(devWh[
381 | new RawGestureDetector(
382 | gestures: {
383 | ScaleRotateGestureRecognizer:
384 | new GestureRecognizerFactoryWithHandlers<
385 | ScaleRotateGestureRecognizer>(
386 | () => new ScaleRotateGestureRecognizer(),
387 | (ScaleRotateGestureRecognizer instance) {
388 | instance
389 | ..onStart = onScaleStart
390 | ..onUpdate = onScaleUpdate
391 | ..onEnd = onScaleEnd;
392 | },
393 | ),
394 | },
395 | child:new RepaintBoundary(
396 | key: globalKey,
397 | child:new Container(
398 | margin: const EdgeInsets.only(
399 | left: 0.0, top: 0.0, right: 0.0, bottom: 0.0),
400 | padding: const EdgeInsets.only(
401 | left: 0.0, top: 0.0, right: 0.0, bottom: 0.0),
402 | color: Colors.black,
403 | width: MediaQuery.of(context).size.width,
404 | height: MediaQuery.of(context).size.height,
405 | child: new CustomSingleChildLayout(
406 | delegate: new ImagePositionDelegate(
407 | imgWidth,
408 | imgHeight,
409 | topLeft),
410 | child: Transform(
411 | child: new RawImage(
412 | image: widget.image,
413 | scale: widget.imageInfo.scale,
414 | ),
415 | alignment: FractionalOffset.center,
416 | transform: matrix,
417 | ),
418 | ),
419 | ),
420 | ),
421 | ),
422 | new Positioned(
423 | left: 0.0,
424 | top: 0.0,
425 | width: MediaQuery.of(context).size.width,
426 | height: maskTop,
427 | child: new IgnorePointer(
428 | child: new Opacity(
429 | opacity: opacity,
430 | child: new Container(
431 | color: Colors.black,
432 | ),
433 | ))),
434 | new Positioned(
435 | left: 0.0,
436 | top: maskTop,
437 | width: this.maskLeft,
438 | height: this.maskHeight,
439 | child: new IgnorePointer(
440 | child: new Opacity(
441 | opacity: opacity,
442 | child: new Container(color: Colors.black),
443 | ))),
444 | new Positioned(
445 | right: 0.0,
446 | top: maskTop,
447 | width: (MediaQuery.of(context).size.width -
448 | this.maskWidth -
449 | this.maskLeft),
450 | height: this.maskHeight,
451 | child: new IgnorePointer(
452 | child: new Opacity(
453 | opacity: opacity,
454 | child: new Container(color: Colors.black),
455 | ))),
456 | new Positioned(
457 | left: 0.0,
458 | top: this.maskTop + this.maskHeight,
459 | width: MediaQuery.of(context).size.width,
460 | height: MediaQuery.of(context).size.height -
461 | (this.maskTop + this.maskHeight),
462 | child: new IgnorePointer(
463 | child: new Opacity(
464 | opacity: opacity,
465 | child: new Container(color: Colors.black),
466 | ))),
467 | new Positioned(
468 | left: this.maskLeft,
469 | top: this.maskTop,
470 | width: this.maskWidth,
471 | height: this.maskHeight,
472 | child: new GestureDetector(
473 | child: new Container(
474 | color: Colors.transparent,
475 | child: new CustomPaint(
476 | painter: new GridPainter(),
477 | ),
478 | ),
479 | onPanStart: onMaskPanStart,
480 | onPanUpdate: (dragInfo) {
481 |
482 | this.onPanUpdate(maskDirection, dragInfo);
483 | },
484 | onPanEnd: onPanEnd
485 | )
486 | ),
487 | new Positioned( //scan
488 | left: this.maskLeft,
489 | top: this.maskTop,
490 | width: this.maskWidth,
491 | height: this.maskHeight*_controller.value,
492 | child: new Opacity(
493 | opacity: 0.5,
494 | child: new Container(color: Colors.blue),
495 | )
496 | ),
497 | new Positioned(
498 | top: maskTop - 2,
499 | left: this.maskLeft - 2,
500 | child: new GestureDetector(
501 | child: new Image.asset("images/topLeft.png"),
502 | onPanStart: onPanStart,
503 | onPanUpdate: (dragInfo) {
504 | this.onPanUpdate("topleft", dragInfo);
505 | },
506 | onPanEnd: onPanEnd),
507 | ),
508 | new Positioned(
509 | top: maskTop - 2,
510 | right: (MediaQuery.of(context).size.width -
511 | this.maskWidth -
512 | this.maskLeft -
513 | 2),
514 | child: new GestureDetector(
515 | child: new Image.asset("images/topRight.png"),
516 | onPanStart: onPanStart,
517 | onPanUpdate: (dragInfo) {
518 | this.onPanUpdate("topright", dragInfo);
519 | },
520 | onPanEnd: onPanEnd
521 | ),
522 | ),
523 | new Positioned(
524 | top: this.maskTop + this.maskHeight - 12.0,
525 | left: this.maskLeft - 2,
526 | child: new GestureDetector(
527 | child: new Image.asset("images/bottomLeft.png"),
528 | onPanStart: onPanStart,
529 | onPanUpdate: (dragInfo) {
530 | this.onPanUpdate("bottomleft", dragInfo);
531 | },
532 | onPanEnd: onPanEnd),
533 | ),
534 | new Positioned(
535 | top: this.maskTop + this.maskHeight - 12.0,
536 | right: (MediaQuery.of(context).size.width -
537 | this.maskWidth -
538 | this.maskLeft -
539 | 2),
540 | child: new GestureDetector(
541 | child: new Image.asset("images/bottomRight.png"),
542 | onPanStart: onPanStart,
543 | onPanUpdate: (dragInfo) {
544 | this.onPanUpdate("bottomright", dragInfo);
545 | },
546 | onPanEnd: onPanEnd,
547 | ),
548 | ),
549 | new Positioned(
550 | bottom: 10.0,
551 | height: 40.0,
552 | width: 40.0,
553 | left: (20.0),
554 | child: new RaisedButton(
555 | onPressed: () => Navigator.pop(context,""),
556 | padding: EdgeInsets.all(10.0),
557 | splashColor: Colors.white,
558 | shape: new RoundedRectangleBorder(
559 | borderRadius: BorderRadius.all(Radius.circular(40.0))),
560 | child: new Icon(Imgcrop.back, size: 20.0, color: Colors.red)
561 | ),
562 | ),
563 | new Positioned(
564 | bottom: 10.0,
565 | height: 40.0,
566 | width: 40.0,
567 | right: 20.0,
568 | child: new RaisedButton(
569 | onPressed: doCapturePng,
570 | padding: EdgeInsets.all(10.0),
571 | splashColor: Colors.white,
572 | shape: new RoundedRectangleBorder(
573 | borderRadius: BorderRadius.all(Radius.circular(40.0))),
574 | child: new Icon(Imgcrop.check, size: 20.0, color: Colors.red)),
575 | )
576 | ],
577 | );
578 | }
579 |
580 | @override
581 | Widget build(BuildContext context) {
582 | return new Scaffold(
583 | body: new Center(
584 | child: new Container(
585 | child: new Column(children: [
586 | new Expanded(child: new Center(child: _buildImage(context))),
587 | //_buildButtons()
588 | ]))), // This trailing comma makes auto-formatting nicer for build methods.
589 | );
590 | }
591 | @override
592 | void dispose() {
593 | _controller.dispose();
594 | super.dispose();
595 | }
596 | }
597 |
598 | class GridPainter extends CustomPainter {
599 | GridPainter();
600 |
601 | @override
602 | void paint(Canvas canvas, Size size) {
603 | Paint paint = new Paint()
604 | ..color = Colors.white
605 | ..strokeCap = StrokeCap.round
606 | ..isAntiAlias = true;
607 |
608 | for (int i = 0; i <= 3; i++) {
609 | if (i == 0 || i == 3) {
610 | paint.strokeWidth = 3.0;
611 | } else {
612 | paint.strokeWidth = 1.0;
613 | }
614 | double dy = (size.height / 3) * i;
615 | canvas.drawLine(new Offset(0.0, dy), new Offset(size.width, dy), paint);
616 | }
617 | for (int i = 0; i <= 3; i++) {
618 | if (i == 0 || i == 3) {
619 | paint.strokeWidth = 3.0;
620 | } else {
621 | paint.strokeWidth = 1.0;
622 | }
623 | double dx = (size.width / 3) * i;
624 | canvas.drawLine(new Offset(dx, 0.0), new Offset(dx, size.height), paint);
625 | }
626 | }
627 |
628 | @override
629 | bool shouldRepaint(CustomPainter oldDelegate) {
630 | return true;
631 | }
632 | }
633 |
634 | class ImagePositionDelegate extends SingleChildLayoutDelegate {
635 | final double imageWidth;
636 | final double imageHeight;
637 | final Offset topLeft;
638 |
639 | const ImagePositionDelegate(this.imageWidth, this.imageHeight, this.topLeft);
640 |
641 | @override
642 | Offset getPositionForChild(Size size, Size childSize) {
643 | return topLeft;
644 | }
645 |
646 | @override
647 | BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
648 | return new BoxConstraints(
649 | maxWidth: imageWidth,
650 | maxHeight: imageHeight,
651 | minHeight: imageHeight,
652 | minWidth: imageWidth,
653 | );
654 | }
655 |
656 | @override
657 | bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) {
658 | return true;
659 | }
660 | }
661 |
--------------------------------------------------------------------------------
/lib/imgcrop_icons.dart:
--------------------------------------------------------------------------------
1 | /// Flutter icons Imgcrop
2 | /// Copyright (C) 2018 by original authors @ fluttericon.com, fontello.com
3 | /// This font was generated by FlutterIcon.com, which is derived from Fontello.
4 | ///
5 | /// To use this font, place it in your fonts/ directory and include the
6 | /// following in your pubspec.yaml
7 | ///
8 | /// flutter:
9 | /// fonts:
10 | /// - family: Imgcrop
11 | /// fonts:
12 | /// - asset: fonts/Imgcrop.ttf
13 | ///
14 | ///
15 | /// * Typicons, (c) Stephen Hutchings 2012
16 | /// Author: Stephen Hutchings
17 | /// License: SIL (http://scripts.sil.org/OFL)
18 | /// Homepage: http://typicons.com/
19 | /// * Material Design Icons, Copyright (C) Google, Inc
20 | /// Author: Google
21 | /// License: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
22 | /// Homepage: https://design.google.com/icons/
23 | /// * Entypo, Copyright (C) 2012 by Daniel Bruce
24 | /// Author: Daniel Bruce
25 | /// License: SIL (http://scripts.sil.org/OFL)
26 | /// Homepage: http://www.entypo.com
27 | /// * Font Awesome, Copyright (C) 2016 by Dave Gandy
28 | /// Author: Dave Gandy
29 | /// License: SIL ()
30 | /// Homepage: http://fortawesome.github.com/Font-Awesome/
31 | ///
32 | import 'package:flutter/widgets.dart';
33 |
34 | class Imgcrop {
35 | Imgcrop._();
36 |
37 | static const _kFontFam = 'Imgcrop';
38 |
39 | static const IconData picture_outline = const IconData(0xe800, fontFamily: _kFontFam);
40 | static const IconData text = const IconData(0xe801, fontFamily: _kFontFam);
41 | static const IconData back = const IconData(0xe802, fontFamily: _kFontFam);
42 | static const IconData check = const IconData(0xe803, fontFamily: _kFontFam);
43 | static const IconData camera = const IconData(0xe804, fontFamily: _kFontFam);
44 | static const IconData assessment = const IconData(0xe805, fontFamily: _kFontFam);
45 | static const IconData account = const IconData(0xe806, fontFamily: _kFontFam);
46 | static const IconData pdf = const IconData(0xe807, fontFamily: _kFontFam);
47 | static const IconData book = const IconData(0xe808, fontFamily: _kFontFam);
48 | }
49 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/gestures.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/cupertino.dart';
4 | import 'dart:io';
5 | import 'package:image_picker/image_picker.dart';
6 | import 'package:video_player/video_player.dart';
7 | import 'dart:async';
8 | import 'dart:ui' as ui;
9 | import 'imgcrop_icons.dart';
10 | import 'image_page.dart';
11 | import 'text_list.dart';
12 | import 'package:camera/camera.dart';
13 | import 'package:path_provider/path_provider.dart';
14 | import 'package:flutter/services.dart';
15 |
16 | List cameras;
17 | CameraDescription camera;
18 |
19 | Future main() async {
20 | cameras = await availableCameras();
21 | camera = cameras[0];
22 | runApp(new MyApp());
23 | }
24 |
25 | class MyApp extends StatelessWidget {
26 | @override
27 | Widget build(BuildContext context) {
28 | return new MaterialApp(
29 | title: 'croper',
30 | theme: new ThemeData(
31 | primarySwatch: Colors.brown,
32 | ),
33 | home: new MyHomePage(title: 'croper'),
34 | );
35 | }
36 | }
37 |
38 | class MyHomePage extends StatefulWidget {
39 | MyHomePage({Key key, this.title}) : super(key: key);
40 | final String title;
41 |
42 | @override
43 | _MyHomePageState createState() => new _MyHomePageState();
44 | }
45 |
46 | class _MyHomePageState extends State with WidgetsBindingObserver {
47 | CameraController controller;
48 | VideoPlayerController _controller;
49 | double maskTop = 60.0;
50 | double maskLeft = 60.0;
51 | double maskWidth = 200.0;
52 | double maskHeight = 200.0;
53 | double dragStartX = 0.0;
54 | double dragStartY = 0.0;
55 | double imgDragStartX = 0.0;
56 | double imgDragStartY = 0.0;
57 | double oldScale = 1.0;
58 | double oldRotate = 0.0;
59 | double rotate = 0.0;
60 | ImageInfo imageInfo;
61 | Offset topLeft = new Offset(0.0, 0.0);
62 | Matrix4 matrix = new Matrix4.identity();
63 |
64 | @override
65 | void initState() {
66 | super.initState();
67 | initCamera();
68 | SystemChannels.lifecycle.setMessageHandler((msg) {
69 | if (msg == AppLifecycleState.resumed.toString()) {
70 | reloadCamera();
71 | }
72 | });
73 | }
74 |
75 | void reloadCamera() {
76 | availableCameras().then((cameras) {
77 | camera = cameras[0];
78 | controller = new CameraController(camera, ResolutionPreset.medium);
79 | controller.initialize().then((_) {
80 | if (!mounted) {
81 | return;
82 | }
83 | setState(() {});
84 | });
85 | });
86 | }
87 |
88 | void initCamera() async {
89 | controller = new CameraController(camera, ResolutionPreset.medium);
90 | controller.initialize().then((_) {
91 | if (!mounted) {
92 | return;
93 | }
94 | setState(() {});
95 | });
96 | }
97 |
98 | void captureImage(ImageSource captureMode) async {
99 | try {
100 | var imageFile = await ImagePicker.pickImage(source: captureMode);
101 | _loadImage(imageFile).then((image) {
102 | if (image != null) {
103 | Navigator.push(
104 | context,
105 | new MaterialPageRoute(
106 | builder: (context) => new CropPage(
107 | title: 'crop',
108 | image: image,
109 | imageInfo: new ImageInfo(image: image, scale: 1.0))));
110 | }
111 | });
112 | } catch (e) {
113 | print(e);
114 | }
115 | }
116 |
117 | @override
118 | void dispose() {
119 | super.dispose();
120 | }
121 |
122 | String timestamp() => new DateTime.now().millisecondsSinceEpoch.toString();
123 |
124 | Future capture() async {
125 | if (!controller.value.initialized) {
126 | return null;
127 | }
128 | final Directory extDir = await getApplicationDocumentsDirectory();
129 | final String dirPath = '${extDir.path}/Pictures/imgcroper';
130 | await new Directory(dirPath).create(recursive: true);
131 | final String filePath = '$dirPath/${timestamp()}.jpg';
132 | try {
133 | await controller.capture(filePath);
134 | try {
135 | File imageFile = new File(filePath);
136 | _loadImage(imageFile).then((image) {
137 | Navigator.push(
138 | context,
139 | new MaterialPageRoute(
140 | builder: (context) => new CropPage(
141 | title: 'crop',
142 | image: image,
143 | imageInfo: new ImageInfo(image: image, scale: 1.0))));
144 | });
145 | } catch (e) {
146 | print(e);
147 | }
148 | } on CameraException catch (e) {
149 | return null;
150 | }
151 | return filePath;
152 | }
153 |
154 | Future _buildImage(BuildContext context) async {
155 | return new Stack(children: [
156 | new Container(
157 | height: MediaQuery.of(context).size.height,
158 | width: MediaQuery.of(context).size.width,
159 | child: new Transform.scale(
160 | scale: 1 / controller.value.aspectRatio,
161 | child: new Center(
162 | child: new AspectRatio(
163 | aspectRatio: controller.value.aspectRatio,
164 | child: new CameraPreview(controller)),
165 | ))),
166 | new Positioned(
167 | bottom: 20.0,
168 | height: 40.0,
169 | width: 40.0,
170 | left: (20.0),
171 | child: new RaisedButton(
172 | onPressed: () => captureImage(ImageSource.gallery),
173 | padding: EdgeInsets.all(10.0),
174 | shape: new RoundedRectangleBorder(
175 | borderRadius: BorderRadius.all(Radius.circular(40.0))),
176 | child: new Icon(Imgcrop.picture_outline,
177 | size: 20.0, color: Colors.red)),
178 | ),
179 | new Positioned(
180 | bottom: 20.0,
181 | height: 60.0,
182 | width: 60.0,
183 | left: (MediaQuery.of(context).size.width / 2 - 30.0),
184 | child: new RaisedButton(
185 | onPressed: capture,
186 | padding: EdgeInsets.all(10.0),
187 | shape: new RoundedRectangleBorder(
188 | borderRadius: BorderRadius.all(Radius.circular(60.0))),
189 | child: new Icon(Imgcrop.camera, size: 40.0, color: Colors.red)),
190 | ),
191 | new Positioned(
192 | bottom: 20.0,
193 | height: 40.0,
194 | width: 40.0,
195 | right: (20.0),
196 | child: new RaisedButton(
197 | onPressed: goToTextListPage,
198 | padding: EdgeInsets.all(10.0),
199 | shape: new RoundedRectangleBorder(
200 | borderRadius: BorderRadius.all(Radius.circular(40.0))),
201 | child: new Icon(Imgcrop.book, size: 20.0, color: Colors.red)),
202 | ),
203 | ]);
204 | }
205 |
206 | void goToTextListPage() {
207 | Navigator.push(this.context,
208 | new MaterialPageRoute(builder: (BuildContext context) {
209 | return new Scaffold(
210 | appBar: new AppBar(
211 | title: new Text("历史记录"),
212 | ),
213 | body: new TextListPage());
214 | }));
215 | }
216 |
217 | Future _loadImage(File img) async {
218 | if (img != null) {
219 | var codec = await ui.instantiateImageCodec(img.readAsBytesSync());
220 | var frame = await codec.getNextFrame();
221 | return frame.image;
222 | }
223 | return null;
224 | }
225 |
226 | @override
227 | Widget build(BuildContext context) {
228 | return new Scaffold(
229 | body: new Center(
230 | child: new Container(
231 | child: new Column(children: [
232 | new Expanded(
233 | child: new Center(
234 | child: new FutureBuilder(
235 | future: _buildImage(context),
236 | builder: (BuildContext context, AsyncSnapshot snapshot) {
237 | if (snapshot.hasData) {
238 | return snapshot.data;
239 | } else {
240 | return new Container();
241 | }
242 | },
243 | ))),
244 | ]))), // This trailing comma makes auto-formatting nicer for build methods.
245 | );
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/lib/result_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/cupertino.dart';
3 | import 'dart:ui' as ui;
4 | import 'imgcrop_icons.dart';
5 |
6 | class ResultPage extends StatefulWidget {
7 | ResultPage({Key key, this.title, this.image, this.ocrContent})
8 | : super(key: key);
9 | final String title;
10 | final ui.Image image;
11 | final List ocrContent;
12 |
13 | @override
14 | ResultState createState() => new ResultState();
15 | }
16 |
17 | class ResultState extends State {
18 | @override
19 | void initState() {
20 | super.initState();
21 | }
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | var height = MediaQuery.of(context).size.height;
26 | var picHeight = 260.0;
27 | var scrollHeight = height - (260.0 + 120.0);
28 | return new Scaffold(
29 | body: new Center(
30 | child: new Stack(children: [
31 | new Container(
32 | child: new Column(children: [
33 | new Container(
34 | child: new RawImage(
35 | image: widget.image,
36 | scale: 0.5,
37 | ),
38 | padding:
39 | const EdgeInsets.only(left: 20.0, top: 30.0, right: 20.0),
40 | height: picHeight),
41 | new Container(
42 | color: Colors.white,
43 | margin: new EdgeInsets.only(top: 60.0),
44 | padding: new EdgeInsets.all(7.0),
45 | height: scrollHeight,
46 | child: new ConstrainedBox(
47 | constraints: new BoxConstraints(
48 | minHeight: scrollHeight,
49 | maxHeight: scrollHeight,
50 | ),
51 | child: new SingleChildScrollView(
52 | scrollDirection: Axis.vertical,
53 | reverse: true,
54 | child: new Text(widget.ocrContent.join("/n").toString()),
55 | ),
56 | ),
57 | )
58 | ]),
59 | ),
60 | new Positioned(
61 | top: 30.0,
62 | height: 40.0,
63 | width: 40.0,
64 | left: 10.0,
65 | child: new RaisedButton(
66 | onPressed: () => Navigator.pop(context, ""),
67 | padding: EdgeInsets.all(10.0),
68 | splashColor: Colors.white,
69 | shape: new RoundedRectangleBorder(
70 | borderRadius: BorderRadius.all(Radius.circular(40.0))),
71 | child: new Icon(Imgcrop.back, size: 20.0, color: Colors.red)),
72 | ),
73 | ])));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib/rotatescale.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | import 'package:flutter/gestures.dart';
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter/cupertino.dart';
8 | import 'dart:math' as math;
9 |
10 |
11 | /// The possible states of a [ScaleGestureRecognizer].
12 | enum _ScaleRotateState {
13 | /// The recognizer is ready to start recognizing a gesture.
14 | ready,
15 |
16 | /// The sequence of pointer events seen thus far is consistent with a scale
17 | /// gesture but the gesture has not been accepted definitively.
18 | possible,
19 |
20 | /// The sequence of pointer events seen thus far has been accepted
21 | /// definitively as a scale gesture.
22 | accepted,
23 |
24 | /// The sequence of pointer events seen thus far has been accepted
25 | /// definitively as a scale gesture and the pointers established a focal point
26 | /// and initial scale.
27 | started,
28 | }
29 |
30 | /// Details for [GestureScaleStartCallback].
31 | class ScaleRotateStartDetails {
32 | /// Creates details for [GestureScaleStartCallback].
33 | ///
34 | /// The [focalPoint] argument must not be null.
35 | ScaleRotateStartDetails({ this.focalPoint: Offset.zero })
36 | : assert(focalPoint != null);
37 |
38 | /// The initial focal point of the pointers in contact with the screen.
39 | /// Reported in global coordinates.
40 | final Offset focalPoint;
41 |
42 | @override
43 | String toString() => 'ScaleRotateStartDetails(focalPoint: $focalPoint)';
44 | }
45 |
46 | /// Details for [GestureScaleUpdateCallback].
47 | class ScaleRotateUpdateDetails {
48 | /// Creates details for [GestureScaleUpdateCallback].
49 | ///
50 | /// The [focalPoint], [scale] and [rotation] arguments must not be null. The [scale]
51 | /// argument must be greater than or equal to zero.
52 | ScaleRotateUpdateDetails({
53 | this.focalPoint: Offset.zero,
54 | this.scale: 1.0,
55 | this.rotation: 0.0,
56 | }) : assert(focalPoint != null),
57 | assert(scale != null && scale >= 0.0),
58 | assert(rotation != null);
59 |
60 | /// The focal point of the pointers in contact with the screen. Reported in
61 | /// global coordinates.
62 | final Offset focalPoint;
63 |
64 | /// The scale implied by the pointers in contact with the screen. A value
65 | /// greater than or equal to zero.
66 | final double scale;
67 |
68 | /// The Rotation implied by the first two pointers to enter in contact with
69 | /// the screen. Expressed in radians.
70 | final double rotation;
71 |
72 | @override
73 | String toString() => 'ScaleRotateUpdateDetails(focalPoint: $focalPoint, scale: $scale, rotation: $rotation)';
74 | }
75 |
76 | /// Details for [GestureScaleEndCallback].
77 | class ScaleRotateEndDetails {
78 | /// Creates details for [GestureScaleEndCallback].
79 | ///
80 | /// The [velocity] argument must not be null.
81 | ScaleRotateEndDetails({ this.velocity: Velocity.zero })
82 | : assert(velocity != null);
83 |
84 | /// The velocity of the last pointer to be lifted off of the screen.
85 | final Velocity velocity;
86 |
87 | @override
88 | String toString() => 'ScaleRotateEndDetails(velocity: $velocity)';
89 | }
90 |
91 | /// Signature for when the pointers in contact with the screen have established
92 | /// a focal point and initial scale of 1.0.
93 | typedef void GestureRotateScaleStartCallback(ScaleRotateStartDetails details);
94 |
95 | /// Signature for when the pointers in contact with the screen have indicated a
96 | /// new focal point and/or scale.
97 | typedef void GestureRotateScaleUpdateCallback(ScaleRotateUpdateDetails details);
98 |
99 | /// Signature for when the pointers are no longer in contact with the screen.
100 | typedef void GestureRotateScaleEndCallback(ScaleRotateEndDetails details);
101 |
102 | bool _isFlingGesture(Velocity velocity) {
103 | assert(velocity != null);
104 | final double speedSquared = velocity.pixelsPerSecond.distanceSquared;
105 | return speedSquared > kMinFlingVelocity * kMinFlingVelocity;
106 | }
107 |
108 |
109 | /// Defines a line between two pointers on screen.
110 | ///
111 | /// [_LineBetweenPointers] is an abstraction of a line between two pointers in
112 | /// contact with the screen. Used to track the rotation of a scale gesture.
113 | class _LineBetweenPointers{
114 |
115 | /// Creates a [_LineBetweenPointers]. None of the [pointerStartLocation], [pointerStartId]
116 | /// [pointerEndLocation] and [pointerEndId] must be null. [pointerStartId] and [pointerEndId]
117 | /// should be different.
118 | _LineBetweenPointers({
119 | this.pointerStartLocation,
120 | this.pointerStartId,
121 | this.pointerEndLocation,
122 | this.pointerEndId
123 | }) : assert(pointerStartLocation != null && pointerEndLocation != null),
124 | assert(pointerStartId != null && pointerEndId != null),
125 | assert(pointerStartId != pointerEndId);
126 |
127 | /// The location and the id of the pointer that marks the start of the line,
128 | final Offset pointerStartLocation;
129 | final int pointerStartId;
130 |
131 | /// The location and the id of the pointer that marks the end of the line,
132 | final Offset pointerEndLocation;
133 | final int pointerEndId;
134 |
135 | }
136 |
137 |
138 | /// Recognizes a scale gesture.
139 | ///
140 | /// [ScaleGestureRecognizer] tracks the pointers in contact with the screen and
141 | /// calculates their focal point, indicated scale and rotation. When a focal pointer is
142 | /// established, the recognizer calls [onStart]. As the focal point, scale and rotation
143 | /// change, the recognizer calls [onUpdate]. When the pointers are no longer in
144 | /// contact with the screen, the recognizer calls [onEnd].
145 | class ScaleRotateGestureRecognizer extends OneSequenceGestureRecognizer {
146 | /// Create a gesture recognizer for interactions intended for scaling content.
147 | ScaleRotateGestureRecognizer({ Object debugOwner }) : super(debugOwner: debugOwner);
148 |
149 | /// The pointers in contact with the screen have established a focal point and
150 | /// initial scale of 1.0.
151 | GestureRotateScaleStartCallback onStart;
152 |
153 | /// The pointers in contact with the screen have indicated a new focal point
154 | /// and/or scale.
155 | GestureRotateScaleUpdateCallback onUpdate;
156 |
157 | /// The pointers are no longer in contact with the screen.
158 | GestureRotateScaleEndCallback onEnd;
159 |
160 | _ScaleRotateState _state = _ScaleRotateState.ready;
161 |
162 | Offset _initialFocalPoint;
163 | Offset _currentFocalPoint;
164 | double _initialSpan;
165 | double _currentSpan;
166 | _LineBetweenPointers _initialLine;
167 | _LineBetweenPointers _currentLine;
168 | Map _pointerLocations;
169 | /// A queue to sort pointers in order of entrance
170 | List _pointerQueue;
171 | final Map _velocityTrackers = {};
172 |
173 | double get _scaleFactor => _initialSpan > 0.0 ? _currentSpan / _initialSpan : 1.0;
174 |
175 | double _rotationFactor () {
176 | if(_initialLine == null || _currentLine == null){
177 | return 0.0;
178 | }
179 | final double fx = _initialLine.pointerStartLocation.dx;
180 | final double fy = _initialLine.pointerStartLocation.dy;
181 | final double sx = _initialLine.pointerEndLocation.dx;
182 | final double sy = _initialLine.pointerEndLocation.dy;
183 |
184 | final double nfx = _currentLine.pointerStartLocation.dx;
185 | final double nfy = _currentLine.pointerStartLocation.dy;
186 | final double nsx = _currentLine.pointerEndLocation.dx;
187 | final double nsy = _currentLine.pointerEndLocation.dy;
188 |
189 | final double angle1 = math.atan2(fy - sy, fx - sx);
190 | final double angle2 = math.atan2(nfy - nsy, nfx - nsx);
191 |
192 | return angle2 - angle1;
193 | }
194 |
195 | @override
196 | void addPointer(PointerEvent event) {
197 | startTrackingPointer(event.pointer);
198 | _velocityTrackers[event.pointer] = new VelocityTracker();
199 | if (_state == _ScaleRotateState.ready) {
200 | _state = _ScaleRotateState.possible;
201 | _initialSpan = 0.0;
202 | _currentSpan = 0.0;
203 | _pointerLocations = {};
204 | _pointerQueue = [];
205 | }
206 | }
207 |
208 | @override
209 | void handleEvent(PointerEvent event) {
210 | assert(_state != _ScaleRotateState.ready);
211 | bool didChangeConfiguration = false;
212 | bool shouldStartIfAccepted = false;
213 | if (event is PointerMoveEvent) {
214 | final VelocityTracker tracker = _velocityTrackers[event.pointer];
215 | assert(tracker != null);
216 | if (!event.synthesized)
217 | tracker.addPosition(event.timeStamp, event.position);
218 | _pointerLocations[event.pointer] = event.position;
219 | shouldStartIfAccepted = true;
220 | } else if (event is PointerDownEvent) {
221 | _pointerLocations[event.pointer] = event.position;
222 | _pointerQueue.add(event.pointer);
223 | didChangeConfiguration = true;
224 | shouldStartIfAccepted = true;
225 | } else if (event is PointerUpEvent || event is PointerCancelEvent) {
226 | _pointerLocations.remove(event.pointer);
227 | _pointerQueue.remove(event.pointer);
228 | didChangeConfiguration = true;
229 | }
230 |
231 | _updateLines();
232 | _update();
233 |
234 | if (!didChangeConfiguration || _reconfigure(event.pointer))
235 | _advanceStateMachine(shouldStartIfAccepted);
236 | stopTrackingIfPointerNoLongerDown(event);
237 | }
238 |
239 | void _update() {
240 | final int count = _pointerLocations.keys.length;
241 |
242 | // Compute the focal point
243 | Offset focalPoint = Offset.zero;
244 | for (int pointer in _pointerLocations.keys)
245 | focalPoint += _pointerLocations[pointer];
246 | _currentFocalPoint = count > 0 ? focalPoint / count.toDouble() : Offset.zero;
247 |
248 | // Span is the average deviation from focal point
249 | double totalDeviation = 0.0;
250 | for (int pointer in _pointerLocations.keys)
251 | totalDeviation += (_currentFocalPoint - _pointerLocations[pointer]).distance;
252 | _currentSpan = count > 0 ? totalDeviation / count : 0.0;
253 | }
254 |
255 | /// Updates [_initialLine] and [_currentLine] accordingly to the situation of
256 | /// the registered pointers
257 | void _updateLines(){
258 | final int count = _pointerLocations.keys.length;
259 |
260 | /// In case of just one pointer registered, reconfigure [_initialLine]
261 | if(count < 2 ){
262 | _initialLine = _currentLine;
263 | } else if(_initialLine != null
264 | && _initialLine.pointerStartId == _pointerQueue[0]
265 | && _initialLine.pointerEndId == _pointerQueue[1]){
266 | /// Rotation updated, set the [_currentLine]
267 | _currentLine = new _LineBetweenPointers(
268 | pointerStartId: _pointerQueue[0],
269 | pointerStartLocation: _pointerLocations[_pointerQueue[0]],
270 | pointerEndId: _pointerQueue[1],
271 | pointerEndLocation: _pointerLocations[ _pointerQueue[1]]
272 | );
273 | } else {
274 | /// A new rotation process is on the way, set the [_initialLine]
275 | _initialLine = new _LineBetweenPointers(
276 | pointerStartId: _pointerQueue[0],
277 | pointerStartLocation: _pointerLocations[_pointerQueue[0]],
278 | pointerEndId: _pointerQueue[1],
279 | pointerEndLocation: _pointerLocations[ _pointerQueue[1]]
280 | );
281 | _currentLine = null;
282 | }
283 | }
284 |
285 | bool _reconfigure(int pointer) {
286 | _initialFocalPoint = _currentFocalPoint;
287 | _initialSpan = _currentSpan;
288 | _initialLine = _currentLine;
289 | if (_state == _ScaleRotateState.started) {
290 | if (onEnd != null) {
291 | final VelocityTracker tracker = _velocityTrackers[pointer];
292 | assert(tracker != null);
293 |
294 | Velocity velocity = tracker.getVelocity();
295 | if (_isFlingGesture(velocity)) {
296 | final Offset pixelsPerSecond = velocity.pixelsPerSecond;
297 | if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity)
298 | velocity = new Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity);
299 | invokeCallback('onEnd', () => onEnd(new ScaleRotateEndDetails(velocity: velocity)));
300 | } else {
301 | invokeCallback('onEnd', () => onEnd(new ScaleRotateEndDetails(velocity: Velocity.zero)));
302 | }
303 | }
304 | _state = _ScaleRotateState.accepted;
305 | return false;
306 | }
307 | return true;
308 | }
309 |
310 | void _advanceStateMachine(bool shouldStartIfAccepted) {
311 | if (_state == _ScaleRotateState.ready)
312 | _state = _ScaleRotateState.possible;
313 |
314 | if (_state == _ScaleRotateState.possible) {
315 | final double spanDelta = (_currentSpan - _initialSpan).abs();
316 | final double focalPointDelta = (_currentFocalPoint - _initialFocalPoint).distance;
317 | if (spanDelta > kScaleSlop || focalPointDelta > kPanSlop)
318 | resolve(GestureDisposition.accepted);
319 | } else if (_state.index >= _ScaleRotateState.accepted.index) {
320 | resolve(GestureDisposition.accepted);
321 | }
322 |
323 | if (_state == _ScaleRotateState.accepted && shouldStartIfAccepted) {
324 | _state = _ScaleRotateState.started;
325 | _dispatchOnStartCallbackIfNeeded();
326 | }
327 |
328 | if (_state == _ScaleRotateState.started && onUpdate != null)
329 | invokeCallback('onUpdate', () => onUpdate(new ScaleRotateUpdateDetails(scale: _scaleFactor, focalPoint: _currentFocalPoint, rotation: _rotationFactor())));
330 | }
331 |
332 | void _dispatchOnStartCallbackIfNeeded() {
333 | assert(_state == _ScaleRotateState.started);
334 | if (onStart != null)
335 | invokeCallback('onStart', () => onStart(new ScaleRotateStartDetails(focalPoint: _currentFocalPoint)));
336 | }
337 |
338 | @override
339 | void acceptGesture(int pointer) {
340 | if (_state == _ScaleRotateState.possible) {
341 | _state = _ScaleRotateState.started;
342 | _dispatchOnStartCallbackIfNeeded();
343 | }
344 | }
345 |
346 | @override
347 | void rejectGesture(int pointer) {
348 | stopTrackingPointer(pointer);
349 | }
350 |
351 | @override
352 | void didStopTrackingLastPointer(int pointer) {
353 | switch (_state) {
354 | case _ScaleRotateState.possible:
355 | resolve(GestureDisposition.rejected);
356 | break;
357 | case _ScaleRotateState.ready:
358 | assert(false); // We should have not seen a pointer yet
359 | break;
360 | case _ScaleRotateState.accepted:
361 | break;
362 | case _ScaleRotateState.started:
363 | assert(false); // We should be in the accepted state when user is done
364 | break;
365 | }
366 | _state = _ScaleRotateState.ready;
367 | }
368 |
369 | @override
370 | void dispose() {
371 | _velocityTrackers.clear();
372 | super.dispose();
373 | }
374 |
375 | @override
376 | String get debugDescription => 'scale';
377 | }
--------------------------------------------------------------------------------
/lib/text_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'dart:async';
3 | import 'package:flutter/cupertino.dart';
4 |
5 | class TextListPage extends StatefulWidget {
6 | TextListPage({Key key, this.title}) : super(key: key);
7 | final String title;
8 |
9 | @override
10 | TextListState createState() => new TextListState();
11 | }
12 |
13 | class TextListState extends State {
14 | Future _dataFuture;
15 |
16 | Future loadFeeds() async {
17 | List resultList = ['曾经的你', '再见理想', '平凡之路', '两天'];
18 | return resultList;
19 | }
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 | _dataFuture = loadFeeds();
25 | }
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return new FutureBuilder(
30 | future: _dataFuture,
31 | builder: (BuildContext context, AsyncSnapshot snapshot) {
32 | switch (snapshot.connectionState) {
33 | case ConnectionState.active:
34 | return new Text("active");
35 | case ConnectionState.none:
36 | return new Center(
37 | child: new Text("none"),
38 | );
39 | case ConnectionState.waiting:
40 | return new Center(
41 | child: new CupertinoActivityIndicator(),
42 | );
43 | default:
44 | if (snapshot.hasError) {
45 | debugPrint("${snapshot.error}");
46 | return new Center(
47 | child: new Text('Error: ${snapshot.error}'),
48 | );
49 | } else {
50 | List data = snapshot.data;
51 | if (null == data || data.length == 0) {
52 | return new Center(
53 | child: new Text('No Data'),
54 | );
55 | }
56 | List columns = [];
57 | data.forEach((name) {
58 | columns.add(new ListTile(
59 | leading: new CircleAvatar(
60 | backgroundColor: Colors.brown.shade800,
61 | child: new Text(name.substring(0, 1)),
62 | ),
63 | title: new Text(name),
64 | trailing: const Icon(Icons.music_note),
65 | // onTap: (){
66 | // Navigator.push(this.context,
67 | // new MaterialPageRoute(builder: (BuildContext context) {
68 | // return new Scaffold(
69 | // appBar: new AppBar(
70 | // title: new Text(name),
71 | // ),
72 | // body: new DetailPage(
73 | // ));
74 | // }));
75 | // },
76 | ));
77 | columns.add(const Divider());
78 | });
79 | return new ListView(
80 | shrinkWrap: true,
81 | padding: const EdgeInsets.all(20.0),
82 | children: columns,
83 | );
84 | }
85 | }
86 | });
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_ocr
2 | description: A new Flutter application.
3 |
4 | dependencies:
5 | flutter:
6 | sdk: flutter
7 |
8 | # The following adds the Cupertino Icons font to your application.
9 | # Use with the CupertinoIcons class for iOS style icons.
10 | cupertino_icons: ^0.1.2
11 | path_provider: 0.4.1
12 | video_player: 0.5.2
13 | camera: ^0.1.2
14 | image: 2.0.4
15 | dio:
16 | image_picker:
17 | dev_dependencies:
18 | flutter_test:
19 | sdk: flutter
20 |
21 |
22 | # For information on the generic Dart part of this file, see the
23 | # following page: https://www.dartlang.org/tools/pub/pubspec
24 |
25 | # The following section is specific to Flutter.
26 | flutter:
27 |
28 | # The following line ensures that the Material Icons font is
29 | # included with your application, so that you can use the icons in
30 | # the material Icons class.
31 | uses-material-design: true
32 | assets:
33 | - images/bottomLeft.png
34 | - images/bottomRight.png
35 | - images/topLeft.png
36 | - images/topRight.png
37 | # To add assets to your application, add an assets section, like this:
38 | # assets:
39 | # - images/a_dot_burr.jpeg
40 | # - images/a_dot_ham.jpeg
41 |
42 | # An image asset can refer to one or more resolution-specific "variants", see
43 | # https://flutter.io/assets-and-images/#resolution-aware.
44 |
45 | # For details regarding adding assets from package dependencies, see
46 | # https://flutter.io/assets-and-images/#from-packages
47 |
48 | # To add custom fonts to your application, add a fonts section here,
49 | # in this "flutter" section. Each entry in this list should have a
50 | # "family" key with the font family name, and a "fonts" key with a
51 | # list giving the asset and other descriptors for the font. For
52 | # example:
53 |
54 | fonts:
55 | - family: Imgcrop
56 | fonts:
57 | - asset: fonts/Imgcrop.ttf
58 | # - family: Trajan Pro
59 | # fonts:
60 | # - asset: fonts/TrajanPro.ttf
61 | # - asset: fonts/TrajanPro_Bold.ttf
62 | # weight: 700
63 | #
64 | # For details regarding fonts from package dependencies,
65 | # see https://flutter.io/custom-fonts/#from-packages
66 |
--------------------------------------------------------------------------------