Skip to content

Commit cb0661c

Browse files
committed
support for extra tesseract parameters
1 parent 75384fa commit cb0661c

21 files changed

+549
-383
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,7 @@ fastlane/readme.md
105105
# sha file
106106
*.sha
107107

108+
#android ide
109+
.androidide/
110+
.androidide/*
108111

app/.androidide/editor/openedFiles.json.bak

Whitespace-only changes.

app/src/main/java/io/github/subhamtyagi/ocr/MainActivity.java

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@
5252
import java.util.Collections;
5353
import java.util.Set;
5454
import java.util.stream.Collectors;
55+
import java.util.HashMap;
56+
import java.util.Map;
5557

5658
import io.github.subhamtyagi.ocr.ocr.ImageTextReader;
57-
import io.github.subhamtyagi.ocr.spinner.SpinnerDialog;
5859
import io.github.subhamtyagi.ocr.utils.Constants;
5960
import io.github.subhamtyagi.ocr.utils.SpUtil;
6061
import io.github.subhamtyagi.ocr.utils.Utils;
@@ -75,7 +76,7 @@ public class MainActivity extends AppCompatActivity implements TessBaseAPI.Progr
7576
/**
7677
* A spinner dialog shown on share menu
7778
*/
78-
private SpinnerDialog spinnerDialog;
79+
7980
private ArrayList<String> languagesNames;
8081
private ConvertImageToTextTask convertImageToTextTask;
8182
private File dirBest;
@@ -94,6 +95,8 @@ public class MainActivity extends AppCompatActivity implements TessBaseAPI.Progr
9495
* Page segmentation mode
9596
*/
9697
private int mPageSegMode;
98+
99+
private Map<String, String> parameters;
97100
/**
98101
* AlertDialog for showing when language data doesn't exists
99102
*/
@@ -208,27 +211,11 @@ private void initIntent() {
208211

209212

210213
private void showLanguageSelectionDialog(Uri imageUri) {
211-
spinnerDialog = new SpinnerDialog(MainActivity.this, languagesNames, getString(R.string.select_search_language), R.style.DialogAnimations_SmileWindow);
212-
spinnerDialog.setShowKeyboard(false);
213-
214-
spinnerDialog.bindOnSpinnerListener((item, position) -> {
215-
startOCRFromShareMenu(imageUri, Collections.singleton(new Language(this, item)));
216-
});
217-
218-
spinnerDialog.showSpinnerDialog();
219-
View view = spinnerDialog.getView();
220-
RadioButton radioButton1 = view.findViewById(R.id.rb_language1);
221-
RadioButton radioButton2 = view.findViewById(R.id.rb_language2);
222-
RadioButton radioButton3 = view.findViewById(R.id.rb_language3);
223-
Triple<Set<Language>, Set<Language>, Set<Language>> languages = Utils.getLast3UsedLanguage(this);
224-
225-
radioButton1.setText(languages.getFirst().stream().map(Language::getName).collect(Collectors.joining(", ")));
226-
radioButton2.setText(languages.getSecond().stream().map(Language::getName).collect(Collectors.joining(", ")));
227-
radioButton3.setText(languages.getThird().stream().map(Language::getName).collect(Collectors.joining(", ")));
228-
229-
radioButton1.setOnClickListener(view1 -> startOCRFromShareMenu(imageUri, languages.getFirst()));
230-
radioButton2.setOnClickListener(view1 -> startOCRFromShareMenu(imageUri, languages.getSecond()));
231-
radioButton3.setOnClickListener(view1 -> startOCRFromShareMenu(imageUri, languages.getThird()));
214+
// if (this.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
215+
ShareFragment frag = ShareFragment.newInstance(imageUri,languagesNames);
216+
frag.show(getSupportFragmentManager(), "shareFrag");
217+
// }
218+
232219
}
233220

234221
@Override
@@ -244,7 +231,6 @@ public void startOCRFromShareMenu(Uri imageUri, Set<Language> languages) {
244231
initializeOCR(languages);
245232
Utils.setLastUsedLanguage(this, languages);
246233
// Log.d("radio", "showLanguageSelectionDialog: " + mLanguage);
247-
spinnerDialog.closeSpinnerDialog();
248234
mImageView.setImageURI(imageUri);
249235
if (noLanguageIsMissing(mTrainingDataType, languages)) {
250236
CropImage.activity(imageUri).start(MainActivity.this);
@@ -276,6 +262,7 @@ private void initializeOCR(Set<Language> languages) {
276262
mTrainingDataType = Utils.getTrainingDataType();
277263
Log.d(TAG, "initializeOCR: " + Utils.getLast3UsedLanguage(this).getFirst());
278264
mPageSegMode = Utils.getPageSegMode();
265+
parameters = Utils.getAllParameters();
279266

280267
switch (mTrainingDataType) {
281268
case "best":
@@ -305,6 +292,8 @@ public void run() {
305292
cf.getAbsolutePath(),
306293
languages,
307294
mPageSegMode,
295+
parameters,
296+
Utils.isExtraParameterSet(),
308297
MainActivity.this);
309298
//check if current language data is valid
310299
//if it is invalid(i.e. corrupted, half downloaded, tempered) then delete it

app/src/main/java/io/github/subhamtyagi/ocr/SettingsActivity.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,13 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
3737
}
3838

3939

40+
}
41+
public static class VariableSettingsFragment extends PreferenceFragmentCompat {
42+
@Override
43+
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
44+
setPreferencesFromResource(R.xml.variable_preference, rootKey);
45+
}
46+
47+
4048
}
4149
}
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
package io.github.subhamtyagi.ocr;
2+
3+
import android.content.ClipData;
4+
import android.content.ClipboardManager;
5+
import android.content.Context;
6+
import android.content.DialogInterface;
7+
import android.content.Intent;
8+
import android.net.Uri;
9+
import android.os.Bundle;
10+
import android.text.Editable;
11+
import android.view.LayoutInflater;
12+
import android.view.View;
13+
import android.view.ViewGroup;
14+
import android.view.inputmethod.InputMethodManager;
15+
import android.widget.Button;
16+
import android.widget.ImageButton;
17+
import android.widget.ImageView;
18+
import android.widget.ListView;
19+
import android.graphics.drawable.ColorDrawable;
20+
import android.widget.EditText;
21+
import android.widget.RadioButton;
22+
import com.google.android.material.bottomsheet.BottomSheetBehavior;
23+
import io.github.subhamtyagi.ocr.spinner.ArrayAdapterWithContainsFilter;
24+
import android.text.TextWatcher;
25+
import android.widget.TextView;
26+
import android.widget.Toast;
27+
28+
import androidx.annotation.NonNull;
29+
import androidx.annotation.Nullable;
30+
31+
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
32+
import java.util.ArrayList;
33+
import java.util.Collections;
34+
import kotlin.Triple;
35+
import java.util.Set;
36+
import io.github.subhamtyagi.ocr.utils.Utils;
37+
import java.util.stream.Collectors;
38+
39+
public class ShareFragment extends BottomSheetDialogFragment {
40+
41+
private static final String LANGUAGE = "language";
42+
43+
44+
private Bundle bundle;
45+
static ArrayList<String> items;
46+
OnSpinnerItemClick onSpinnerItemClick;
47+
48+
boolean showKeyboard = false;
49+
boolean useContainsFilter = false;
50+
51+
int pos;
52+
53+
@Nullable
54+
@Override
55+
public View onCreateView(
56+
LayoutInflater inflater,
57+
@Nullable ViewGroup container,
58+
@Nullable Bundle savedInstanceState) {
59+
60+
View vw = inflater.inflate(R.layout.dialog_layout, container, false);
61+
62+
63+
bundle = getArguments();
64+
65+
assert bundle != null;
66+
67+
// BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(vw.findViewById(R.id.mainView));
68+
// bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
69+
// bottomSheetBehavior.setHideable(false);
70+
71+
TextView title = vw.findViewById(R.id.spinerTitle);
72+
ImageView searchIcon = vw.findViewById(R.id.searchIcon);
73+
title.setText(R.string.select_search_language);
74+
75+
final ListView listView = vw.findViewById(R.id.list);
76+
77+
// ColorDrawable sage = new ColorDrawable(itemDividerColor);
78+
// listView.setDivider(sage);
79+
// listView.setDividerHeight(1);
80+
81+
final EditText searchBox = vw.findViewById(R.id.searchBox);
82+
if (isShowKeyboard()) {
83+
showKeyboard(searchBox);
84+
}
85+
86+
final ArrayAdapterWithContainsFilter<String> adapter =
87+
new ArrayAdapterWithContainsFilter<String>(
88+
getActivity(), R.layout.items_view, items) {
89+
@NonNull
90+
@Override
91+
public View getView(
92+
int position, @Nullable View convertView, @NonNull ViewGroup parent) {
93+
View view = super.getView(position, convertView, parent);
94+
TextView text1 = view.findViewById(R.id.text1);
95+
// text1.setTextColor(itemColor);
96+
return view;
97+
}
98+
};
99+
listView.setAdapter(adapter);
100+
101+
listView.setOnItemClickListener(
102+
(adapterView, view, i, l) -> {
103+
TextView t = view.findViewById(R.id.text1);
104+
for (int j = 0; j < items.size(); j++) {
105+
if (t.getText().toString().equalsIgnoreCase(items.get(j))) {
106+
pos = j;
107+
}
108+
}
109+
//onSpinnerItemClick.onClick(t.getText().toString(), pos);
110+
});
111+
112+
searchBox.addTextChangedListener(
113+
new TextWatcher() {
114+
@Override
115+
public void beforeTextChanged(
116+
CharSequence charSequence, int i, int i1, int i2) {}
117+
118+
@Override
119+
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
120+
121+
@Override
122+
public void afterTextChanged(Editable editable) {
123+
if (isUseContainsFilter()) {
124+
adapter.getContainsFilter(searchBox.getText().toString());
125+
} else {
126+
adapter.getFilter().filter(searchBox.getText().toString());
127+
}
128+
}
129+
130+
});
131+
132+
// startOCRFromShareMenu(imageUri, Collections.singleton(new Language(this, item)));
133+
RadioButton radioButton1 = vw.findViewById(R.id.rb_language1);
134+
RadioButton radioButton2 = vw.findViewById(R.id.rb_language2);
135+
RadioButton radioButton3 = vw.findViewById(R.id.rb_language3);
136+
Triple<Set<Language>, Set<Language>, Set<Language>> languages =
137+
Utils.getLast3UsedLanguage(getContext());
138+
139+
radioButton1.setText(
140+
languages.getFirst().stream()
141+
.map(Language::getName)
142+
.collect(Collectors.joining(", ")));
143+
radioButton2.setText(
144+
languages.getSecond().stream()
145+
.map(Language::getName)
146+
.collect(Collectors.joining(", ")));
147+
radioButton3.setText(
148+
languages.getThird().stream()
149+
.map(Language::getName)
150+
.collect(Collectors.joining(", ")));
151+
152+
// radioButton1.setOnClickListener(view1 -> startOCRFromShareMenu(imageUri,
153+
// languages.getFirst()));
154+
// radioButton2.setOnClickListener(view1 -> startOCRFromShareMenu(imageUri,
155+
// languages.getSecond()));
156+
// radioButton3.setOnClickListener(view1 -> startOCRFromShareMenu(imageUri,
157+
// languages.getThird()));
158+
159+
return vw;
160+
}
161+
162+
@Override
163+
public void onCancel(@NonNull DialogInterface dialog) {
164+
cancel();
165+
}
166+
167+
@Override
168+
public void dismiss() {
169+
cancel();
170+
super.dismiss();
171+
}
172+
173+
private void cancel() {}
174+
175+
public static ShareFragment newInstance(Uri imageUri, ArrayList<String> languagesName) {
176+
ShareFragment fragment = new ShareFragment();
177+
items=languagesName;
178+
Bundle bundle = new Bundle();
179+
bundle.putString(LANGUAGE, "string");
180+
fragment.setArguments(bundle);
181+
return fragment;
182+
}
183+
184+
private void hideKeyboard() {
185+
try {
186+
InputMethodManager inputManager =
187+
(InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
188+
// inputManager.hideSoftInputFromWindow(
189+
//getContext().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
190+
} catch (Exception ignore) {
191+
}
192+
}
193+
194+
private void showKeyboard(final EditText ettext) {
195+
ettext.requestFocus();
196+
ettext.postDelayed(
197+
() -> {
198+
InputMethodManager keyboard =
199+
(InputMethodManager)
200+
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
201+
keyboard.showSoftInput(ettext, 0);
202+
},
203+
200);
204+
}
205+
206+
private boolean isShowKeyboard() {
207+
return showKeyboard;
208+
}
209+
210+
public void setShowKeyboard(boolean showKeyboard) {
211+
this.showKeyboard = showKeyboard;
212+
}
213+
214+
private boolean isUseContainsFilter() {
215+
return useContainsFilter;
216+
}
217+
218+
public void setUseContainsFilter(boolean useContainsFilter) {
219+
this.useContainsFilter = useContainsFilter;
220+
}
221+
222+
public interface OnSpinnerItemClick {
223+
public void onClick(String item, int position);
224+
}
225+
}

app/src/main/java/io/github/subhamtyagi/ocr/ocr/ImageTextReader.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44

55
import com.googlecode.tesseract.android.TessBaseAPI;
66

7+
import io.github.subhamtyagi.ocr.Language;
78
import java.util.Set;
89
import java.util.stream.Collectors;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
import io.github.subhamtyagi.ocr.utils.Constants;
14+
915

10-
import io.github.subhamtyagi.ocr.Language;
1116

1217
/**
1318
* This class convert the image to text and return the text on image
@@ -29,7 +34,7 @@ public class ImageTextReader {
2934
* @param languages language code i.e. selected by user
3035
* @return the instance of this class for later use
3136
*/
32-
public static ImageTextReader getInstance(String path, Set<Language> languages, int pageSegMode, TessBaseAPI.ProgressNotifier progressNotifier) {
37+
public static ImageTextReader getInstance(String path, Set<Language> languages, int pageSegMode, Map<String, String> parameters, boolean isParameterSet,TessBaseAPI.ProgressNotifier progressNotifier) {
3338
try {
3439
ImageTextReader imageTextReader=new ImageTextReader();
3540
api = new TessBaseAPI(progressNotifier);
@@ -38,6 +43,14 @@ public static ImageTextReader getInstance(String path, Set<Language> languages,
3843
.map(Language::getCode)
3944
.collect(Collectors.joining("+")));
4045
api.setPageSegMode(pageSegMode);
46+
if(isParameterSet)
47+
for (Map.Entry<String, String> entry : parameters.entrySet()) {
48+
String key = entry.getKey();
49+
String value = entry.getValue();
50+
if (!key.equals(Constants.KEY_OCR_PSM_MODE)) {
51+
api.setVariable(key ,value);
52+
}
53+
}
4154
return imageTextReader;
4255
} catch (Exception e) {
4356
return null;

app/src/main/java/io/github/subhamtyagi/ocr/spinner/OnSpinnerItemClick.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)