├── .DS_Store ├── .gitignore ├── README.md └── ScanDemoExample ├── .DS_Store ├── apk └── app-debug.apk ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── scanner │ │ └── demo │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── scanner │ │ └── demo │ │ └── MainActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── build └── intermediates │ ├── dex-cache │ └── cache.xml │ └── model_data.bin ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scanlibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── scanlibrary │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ ├── .DS_Store │ └── com │ │ └── scanlibrary │ │ ├── ExifInterfaceUtils.java │ │ ├── ImageResizer.java │ │ ├── PolygonView.java │ │ ├── ProgressDialogFragment.java │ │ ├── ScalingUtilities.java │ │ ├── ScanActivity.java │ │ ├── ScanFragment.java │ │ ├── ScanUtils.java │ │ └── Utils.java │ ├── libs │ └── armeabi-v7a │ │ └── libopencv_java.so │ └── res │ ├── drawable-hdpi │ ├── ic_color_lens_white_24dp.png │ ├── ic_crop_white_24dp.png │ ├── ic_done_white_24dp.png │ └── ic_rotate_90_degrees_ccw_white_24dp.png │ ├── drawable-mdpi │ ├── ic_color_lens_white_24dp.png │ ├── ic_crop_white_24dp.png │ ├── ic_done_white_24dp.png │ └── ic_rotate_90_degrees_ccw_white_24dp.png │ ├── drawable-xhdpi │ ├── ic_color_lens_white_24dp.png │ ├── ic_crop_white_24dp.png │ ├── ic_done_white_24dp.png │ └── ic_rotate_90_degrees_ccw_white_24dp.png │ ├── drawable-xxhdpi │ ├── ic_color_lens_white_24dp.png │ ├── ic_crop_white_24dp.png │ ├── ic_done_white_24dp.png │ └── ic_rotate_90_degrees_ccw_white_24dp.png │ ├── drawable-xxxhdpi │ ├── ic_color_lens_white_24dp.png │ ├── ic_crop_white_24dp.png │ ├── ic_done_white_24dp.png │ └── ic_rotate_90_degrees_ccw_white_24dp.png │ ├── drawable │ └── circle.xml │ ├── layout │ ├── activity_scan.xml │ └── fragment_scan.xml │ ├── menu │ └── scan_menu.xml │ ├── values-lt │ └── strings.xml │ ├── values-ru │ └── strings.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ └── strings.xml ├── screenshots ├── a.png ├── b.png ├── c.png ├── d.png ├── e.png ├── f.png └── g.png └── settings.gradle /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea/ 3 | *.iml 4 | ScanDemoExample/local.properties 5 | ScanDemoExample/build/intermediates/dex-cache/cache.xml 6 | 7 | ScanDemoExample/build/intermediates/dex-cache/cache.xml 8 | ScanDemoExample/gradle.properties 9 | ScanDemoExample/scanlibrary/gradle.properties 10 | ScanDemoExample/scanlibrary/AndroidDocumentScanner.gpg 11 | ScanDemoExample/gradle.properties 12 | ScanDemoExample/build/intermediates/dex-cache/cache.xml 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ScanLibrary 2 | ScanLibrary is an android document scanning library built on top of OpenCV, using the app you will be able to select the exact edges and crop the document accordingly from the selected 4 edges and change the perspective transformation of the cropped image. 3 | 4 | # Screenshots 5 | 6 |
7 | 8 | Scan Points 9 | 10 | Magic colors 11 | 12 | Palette 13 | 14 | Gray colors 15 | 16 | Normal colors 17 | 18 | Rotated Image 19 | 20 | Zoomed Image 21 |
22 | 23 | # Using it in your project 24 | - If you are using android studio, add the dependency to your main app build.gradle this way: 25 | 26 | ``` 27 | - compile 'com.github.andrejlukasevic:document-scanner:4.0.0' // Check for latest version and replace version code 28 | ``` 29 | - In your activity or fragment when you want to give an option of document scanning to user then: 30 | Start the scanlibrary ScanActivity, with this the app will go to library, below is the sample code snippet: 31 | ```java 32 | Intent intent = new Intent(this, ScanActivity.class); 33 | intent.putExtra(ScanActivity.EXTRA_BRAND_IMG_RES, R.drawable.ic_crop_white_24dp); // Set image for title icon - optional 34 | intent.putExtra(ScanActivity.EXTRA_TITLE, "Crop Document"); // Set title in action Bar - optional 35 | intent.putExtra(ScanActivity.EXTRA_ACTION_BAR_COLOR, R.color.green); // Set title color - optional 36 | intent.putExtra(ScanActivity.EXTRA_LANGUAGE, "en"); // Set language - optional 37 | startActivityForResult(intent, REQUEST_CODE_SCAN); 38 | ``` 39 | 40 | - Once the scanning is done, the application is returned from scan library to main app, to retrieve the scanned image, add onActivityResult in your activity or fragment from where you have started startActivityForResult, below is the sample code snippet: 41 | ```java 42 | @Override 43 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 44 | super.onActivityResult(requestCode, resultCode, data); 45 | if (requestCode == REQUEST_CODE_SCAN && resultCode == Activity.RESULT_OK) { 46 | String imgPath = data.getStringExtra(ScanActivity.RESULT_IMAGE_PATH); 47 | BitmapFactory.Options options = new BitmapFactory.Options(); 48 | options.inPreferredConfig = Bitmap.Config.ARGB_8888; 49 | Bitmap bitmap = BitmapFactory.decodeFile(imgPath, options); 50 | viewHolder.image.setImageBitmap(bitmap); 51 | } 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /ScanDemoExample/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/ScanDemoExample/.DS_Store -------------------------------------------------------------------------------- /ScanDemoExample/apk/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/ScanDemoExample/apk/app-debug.apk -------------------------------------------------------------------------------- /ScanDemoExample/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ScanDemoExample/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.scanner.demo" 9 | minSdkVersion 14 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:21.0.3' 25 | compile 'com.github.andrejlukasevic:document-scanner:4.0.0' // Check for latest version 26 | } 27 | -------------------------------------------------------------------------------- /ScanDemoExample/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/jhansi/softwares/adt-bundle-mac-x86_64-20130729/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /ScanDemoExample/app/src/androidTest/java/com/scanner/demo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.scanner.demo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/java/com/scanner/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.scanner.demo; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.graphics.Bitmap; 6 | import android.os.Bundle; 7 | import android.support.v7.app.ActionBarActivity; 8 | import android.view.View; 9 | import android.view.View.OnClickListener; 10 | import android.widget.ImageView; 11 | 12 | import com.scanlibrary.ScanActivity; 13 | import com.scanlibrary.Utils; 14 | 15 | 16 | public class MainActivity extends ActionBarActivity implements OnClickListener { 17 | 18 | // =========================================================== 19 | // Constants 20 | // =========================================================== 21 | 22 | private static final int REQUEST_CODE_SCAN = 47; 23 | 24 | private static final String SAVED_SCANNED_HHOTO = "scanned_photo"; 25 | 26 | // =========================================================== 27 | // Fields 28 | // =========================================================== 29 | 30 | private final ViewHolder viewHolder = new ViewHolder(); 31 | 32 | private String scannedPhoto; 33 | 34 | // =========================================================== 35 | // Constructors 36 | // =========================================================== 37 | 38 | // =========================================================== 39 | // Getters & Setters 40 | // =========================================================== 41 | 42 | // =========================================================== 43 | // Methods for/from SuperClass/Interfaces 44 | // =========================================================== 45 | 46 | @Override 47 | protected void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | setContentView(R.layout.activity_main); 50 | viewHolder.prepare(findViewById(android.R.id.content)); 51 | 52 | if (savedInstanceState != null) { 53 | scannedPhoto = savedInstanceState.getString(SAVED_SCANNED_HHOTO); 54 | } 55 | 56 | if (scannedPhoto != null) { 57 | viewHolder.image.setImageBitmap(Utils.getBitmapFromLocation(scannedPhoto)); 58 | } 59 | } 60 | 61 | @Override 62 | public void onClick(View v) { 63 | if (v.equals(viewHolder.scabBtn)) { 64 | onScanButtonClicked(); 65 | } 66 | } 67 | 68 | @Override 69 | protected void onResume() { 70 | super.onResume(); 71 | viewHolder.scabBtn.setOnClickListener(this); 72 | } 73 | 74 | @Override 75 | protected void onPause() { 76 | super.onPause(); 77 | viewHolder.scabBtn.setOnClickListener(null); 78 | } 79 | 80 | @Override 81 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 82 | super.onActivityResult(requestCode, resultCode, data); 83 | if (requestCode == REQUEST_CODE_SCAN && resultCode == Activity.RESULT_OK) { 84 | String imgPath = data.getStringExtra(ScanActivity.RESULT_IMAGE_PATH); 85 | Bitmap bitmap = Utils.getBitmapFromLocation(imgPath); 86 | viewHolder.image.setImageBitmap(bitmap); 87 | // Uri uri = data.getExtras().getParcelable(ScanConstants.SCANNED_RESULT); 88 | // Bitmap bitmap = null; 89 | // try { 90 | // bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); 91 | // getContentResolver().delete(uri, null, null); 92 | // viewHolder.image.setImageBitmap(bitmap); 93 | // } catch (IOException e) { 94 | // e.printStackTrace(); 95 | // } 96 | } 97 | } 98 | 99 | @Override 100 | protected void onSaveInstanceState(Bundle outState) { 101 | super.onSaveInstanceState(outState); 102 | outState.putString(SAVED_SCANNED_HHOTO, scannedPhoto); 103 | } 104 | 105 | // =========================================================== 106 | // Methods 107 | // =========================================================== 108 | 109 | private void onScanButtonClicked() { 110 | Intent intent = new Intent(this, ScanActivity.class); 111 | intent.putExtra(ScanActivity.EXTRA_BRAND_IMG_RES, R.drawable.ic_crop_white_24dp); 112 | intent.putExtra(ScanActivity.EXTRA_TITLE, "Crop Document"); 113 | intent.putExtra(ScanActivity.EXTRA_ACTION_BAR_COLOR, R.color.green); 114 | intent.putExtra(ScanActivity.EXTRA_LANGUAGE, "en"); 115 | startActivityForResult(intent, REQUEST_CODE_SCAN); 116 | } 117 | 118 | 119 | // =========================================================== 120 | // Inner and Anonymous Classes 121 | // =========================================================== 122 | 123 | private static class ViewHolder { 124 | 125 | ImageView image; 126 | View scabBtn; 127 | 128 | void prepare(View parent) { 129 | image = (ImageView) parent.findViewById(R.id.image); 130 | scabBtn = parent.findViewById(R.id.scan); 131 | } 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/ScanDemoExample/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/ScanDemoExample/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/ScanDemoExample/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liltof/android-scanner/898dc1335a577533b0c9ef32126fda32a761f5fc/ScanDemoExample/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ScanDemoExample/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 18 | 19 | 24 | 25 |