title: Google Vision api to extract text from a Bitmap
body: <p>I'm trying to develop an application that extracts text from a screenshot and with these data (numbers and texts) I do something. It works but not as I expected, it isn't accurate at all. The strange thing is that the same screenshot at the same resolution is recognized in a different way by my application and the "try api" on <a href="https://cloud.google.com/vision/" rel="nofollow noreferrer">google vision api site</a> </p>
  
  <blockquote>
    <p>for example: a screenshot with "410" as text was recognized as "A10" by my app. Otherwise google api site properly recognizes 410</p>
  </blockquote>
  
  <p>I noticed that google Keep OCR work better than my app, it use the same api? what can i do for improve the text recognition in my app as google Keep or google vison api site? </p>
  
  <p>here is my code:</p>
  
  <blockquote>
    <p>Ocr class</p>
  </blockquote>
  
  <pre><code>public class Ocr extends AppCompatActivity {
  
  private static int RESULT_LOAD_IMAGE = 1;
  
  String TAG = "MAIN ACTIVITY";
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      Button buttonLoadImage = (Button) findViewById(R.id.upload_btn);
  
      buttonLoadImage.setOnClickListener(new View.OnClickListener() {
  
          /**
           * on click method of the upload button
           * @param arg0
           */
          @Override
          public void onClick(View arg0) {
  
              Intent i = new Intent(
                      Intent.ACTION_PICK,
                      android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
  
              startActivityForResult(i, RESULT_LOAD_IMAGE);
          }
      });
  
  }
  
  
  /**
   * In this method, we check if the activity that was triggered was indeed Image Gallery
   * (It is common to trigger different intents from the same activity and expects result from each).
   * For this we used RESULT_LOAD_IMAGE integer that we passed previously to startActivityForResult() method
   * @param requestCode
   * @param resultCode
   * @param data
   */
  
  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
  
      if (requestCode == RESULT_LOAD_IMAGE &amp;&amp; resultCode == RESULT_OK &amp;&amp; data != null &amp;&amp; data.getData() != null) {
  
          Uri uri = data.getData();
  
          try {
              Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
  
              ImageView imageView = (ImageView) findViewById(R.id.imgView);
  
              imageView.setImageBitmap(bitmap);
  
              // imageBitmap is the Bitmap image you're trying to process for text
              if (bitmap != null) {
  
                  TextRecognizer textRecognizer = new TextRecognizer.Builder(this).build();
  
                  if (!textRecognizer.isOperational()) {
                      // Note: The first time that an app using a Vision API is installed on a
                      // device, GMS will download a native libraries to the device in order to do detection.
                      // Usually this completes before the app is run for the first time.  But if that
                      // download has not yet completed, then the above call will not detect any text,
                      // barcodes, or faces.
                      // isOperational() can be used to check if the required native libraries are currently
                      // available.  The detectors will automatically become operational once the library
                      // downloads complete on device.
                      Log.w(TAG, "Detector dependencies are not yet available.");
  
                      // Check for low storage.  If there is low storage, the native library will not be
                      // downloaded, so detection will not become operational.
                      IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
                      boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;
  
                      if (hasLowStorage) {
                          Toast.makeText(this, "Low Storage", Toast.LENGTH_LONG).show();
                          Log.w(TAG, "Low Storage");
                      }
                  }
  
  
                  Frame imageFrame = new Frame.Builder()
                          .setBitmap(bitmap)
                          .build();
  
                  SparseArray&lt;TextBlock&gt; textBlocks = textRecognizer.detect(imageFrame);
  
  
                  for (int i = 0; i &lt; textBlocks.size(); i++) {
  
                      TextBlock textBlock = textBlocks.get(textBlocks.keyAt(i));
  
                      String text = textBlock.getValue();
  
                      Toast.makeText(this, text , Toast.LENGTH_SHORT).show();
  
                  }
              }
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
  
      }
   }
  }
  </code></pre>
  
  <blockquote>
    <p>Android Manifest </p>
  </blockquote>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
     &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.prova.ocr"&gt;
  &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&gt;
  &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/&gt;
  &lt;application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true"
      android:theme="@style/AppTheme"&gt;
      &lt;meta-data
          android:name="com.google.android.gms.version"
          android:value="@integer/google_play_services_version" /&gt;
      &lt;meta-data
          android:name="com.google.android.gms.vision.DEPENDENCIES"
          android:value="ocr" /&gt;
  
      &lt;activity android:name=".MainActivity"&gt;
          &lt;intent-filter&gt;
              &lt;action android:name="android.intent.action.MAIN" /&gt;
  
              &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
          &lt;/intent-filter&gt;
      &lt;/activity&gt;
  &lt;/application&gt;
  </code></pre>
  
  <p></p>
  
  <blockquote>
    <p>Gradle</p>
  </blockquote>
  
  <pre><code>apply plugin: 'com.android.application'
  android {
  compileSdkVersion 25
  buildToolsVersion "25.0.1"
  defaultConfig {
      applicationId "com.prova.ocr"
      minSdkVersion 19
      targetSdkVersion 25
      versionCode 1
      versionName "1.0"
      testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  }
  buildTypes {
      release {
          minifyEnabled false
          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
      }
  }
  }
  
  dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
      exclude group: 'com.android.support', module: 'support-annotations'
      })
  compile 'com.android.support:appcompat-v7:25.0.1'
  testCompile 'junit:junit:4.12'
  compile 'com.android.support:support-v4:25.0.1'
  compile 'com.android.support:design:25.0.1'
  compile 'com.google.android.gms:play-services-vision:10.0.0+'
  }
  </code></pre>