<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Image Recognition Archives - Truiton</title>
	<atom:link href="https://www.truiton.com/tag/image-recognition/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Technology Reaching Us In Time - Online</description>
	<lastBuildDate>Sun, 01 Sep 2019 14:06:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://i0.wp.com/www.truiton.com/wp-content/uploads/2022/11/cropped-truiton_new_logo_half_white.png?fit=32%2C32&#038;ssl=1</url>
	<title>Image Recognition Archives - Truiton</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">54534495</site>	<item>
		<title>Introducing Android Mobile Vision API</title>
		<link>https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/</link>
					<comments>https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Sun, 28 May 2017 17:29:27 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Face Detection]]></category>
		<category><![CDATA[Image Recognition]]></category>
		<category><![CDATA[Mobile Vision API]]></category>
		<category><![CDATA[OCR]]></category>
		<guid isPermaLink="false">http://www.truiton.com/?p=1557</guid>

					<description><![CDATA[<p>In August 2015, Google announced the release of Android Mobile Vision API. At that time this API had mainly three&#160;components Face Detection, Barcode scanner and ways to capture the tracking of objects in real time. But later on some bugs were found in its implementation, due to which the access to this API was restricted&#8230;&#160;<a href="https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Introducing Android Mobile Vision API</span></a></p>
<p>The post <a href="https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/">Introducing Android Mobile Vision API</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="950" height="530" data-attachment-id="1741" data-permalink="https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/android-mobile-vision-featured/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?fit=950%2C530&amp;ssl=1" data-orig-size="950,530" data-comments-opened="1" data-image-title="Android Mobile Vision Featured" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?fit=950%2C530&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?resize=950%2C530" alt="Android Mobile Vision API" class="wp-image-1741" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?w=950&amp;ssl=1 950w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?resize=600%2C335&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?resize=300%2C167&amp;ssl=1 300w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2017/05/Android-Mobile-Vision-Featured.jpg?resize=768%2C428&amp;ssl=1 768w" sizes="(max-width: 950px) 100vw, 950px" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">In August 2015, Google <a href="https://developers.google.com/vision/" target="_blank" rel="noopener noreferrer">announced</a> the release of Android Mobile Vision API. At that time this API had mainly three&nbsp;components Face Detection, Barcode scanner and ways to capture the tracking of objects in real time. But later on some bugs were found in its implementation, due to which the access to this API was restricted by Google&nbsp;to the existing users only. Then recently in <a href="https://developers.google.com/android/guides/releases" target="_blank" rel="noopener noreferrer">June 2016</a> these issues were resolved and Mobile Vision APIs were re-launched. But this time it had a few&nbsp;new features like OCR and scanning of Aztec barcodes. In the next sections lets understand what&nbsp;exactly is the new Mobile Vision API and how can we use it&nbsp;to&nbsp;build an efficient code base.</p>



<h2 class="wp-block-heading">&nbsp;</h2>



<h2 class="wp-block-heading">What is Android Mobile Vision API ?</h2>



<p class="wp-block-paragraph">Ever wondered how to detect a face, a QR code or a Bar code on an Android Device? If yes; you might have heard of, or used the&nbsp;<a href="http://developer.android.com/reference/android/media/FaceDetector.Face.html" target="_blank" rel="noopener noreferrer">FaceDetector.Face</a>&nbsp;API of the Android framework, or the OpenCV SDK, or maybe you had opted for a cloud based solution like <a href="http://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/" target="_blank" rel="noopener noreferrer">Cloud Vision API</a>,&nbsp;which makes the requests to a web server, fetching the results for&nbsp;scans. But this new Android Mobile Vision API does not make any requests to a web server. Instead it performs real time image/video scanning on the device itself. Although this&nbsp;may sound a little in-effective, but its not. The Mobile Vision API is very efficient and deeply integrated in to the Android system by the means of <a href="https://developers.google.com/android/guides/overview" target="_blank" rel="noopener noreferrer">Google Play Services SDK</a>. This gives this API&nbsp;an added advantage over all other solutions, as&nbsp;being&nbsp;a developer you do not need to integrate any third party SDK to perform media analysis. All you may need to do is <a href="https://developers.google.com/android/guides/setup" target="_blank" rel="noopener noreferrer">integrate the Google Play Services</a> properly and start building on it. Android Mobile Vision API as of now performs&nbsp;three types of image/stream detection as shown in next sections.</p>



<h2 class="wp-block-heading">Setting up Android Mobile Vision&nbsp;Library</h2>



<p class="wp-block-paragraph">When speaking of this new&nbsp;multipurpose Android offline image recognition library, the only downside is that one has to set it up before the actual usage. Although it does not mean any manual configuration but&nbsp;a tag needs to be added in the application manifest. So that the installer knows that an extra package is needed to be downloaded as the app is being installed. As of now the mobile vision API has three components, therefore all&nbsp;three&nbsp;dependencies can be included in a single manifest tag under the application tag as shown:</p>



<pre class="wp-block-preformatted lang:default decode:true">&lt;meta-data
            android:name="com.google.android.gms.vision.DEPENDENCIES"
            android:value="barcode,face,ocr"/&gt;</pre>



<p class="wp-block-paragraph">This would instruct the OS to download the packages for all three types of offline image analysis. Next lets have a brief understanding of all the features of this powerful Mobile Vision API.</p>



<h3 class="wp-block-heading">1. Barcode and QR Code scanning on Android</h3>



<p class="wp-block-paragraph">The Barcode Scanner API is used to scan various types of bar codes and qr codes. Some of them are:</p>



<ul class="wp-block-list"><li>1D barcodes: <a href="https://en.wikipedia.org/wiki/International_Article_Number_(EAN)" target="_blank" rel="noopener noreferrer">EAN-13, EAN-8</a>, <a href="https://en.wikipedia.org/wiki/Universal_Product_Code" target="_blank" rel="noopener noreferrer">UPC-A, UPC-E</a>, <a href="https://en.wikipedia.org/wiki/Code_39" target="_blank" rel="noopener noreferrer">Code-39</a>, <a href="https://en.wikipedia.org/wiki/Code_93" target="_blank" rel="noopener noreferrer">Code-93</a>, <a href="https://en.wikipedia.org/wiki/Code_128" target="_blank" rel="noopener noreferrer">Code-128</a>, <a href="https://en.wikipedia.org/wiki/Interleaved_2_of_5" target="_blank" rel="noopener noreferrer">ITF</a>, <a href="https://en.wikipedia.org/wiki/Codabar" target="_blank" rel="noopener noreferrer">Codabar</a></li><li>2D barcodes: <a href="https://en.wikipedia.org/wiki/QR_code" target="_blank" rel="noopener noreferrer">QR Code</a>, <a href="https://en.wikipedia.org/wiki/Data_Matrix" target="_blank" rel="noopener noreferrer">Data Matrix</a>, <a href="https://en.wikipedia.org/wiki/PDF417" target="_blank" rel="noopener noreferrer">PDF-417</a>, <a href="https://en.wikipedia.org/wiki/PDF417" target="_blank" rel="noopener noreferrer">AZTEC</a></li></ul>



<p class="wp-block-paragraph">Using this Mobile Vision API for Bar codes is very simple, even with so many supported formats. All you need to do is write around&nbsp;10&nbsp;lines of code to parse a Barcode or QR Code.&nbsp;One of the most interesting things about this API is that, it also parses the type of barcode/QR code it is scanning.&nbsp;All the information about the scanned barcode or QR Code type is found in the <code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/barcode/Barcode.html#valueFormat">valueFormat</a> field of Barcode Object besides the scanned barcode. To learn more about the usage of Barcode Scanner API of the Android Mobile Vision API please refer to this tutorial:</p>



<p class="wp-block-paragraph" style="text-align:center"><a class="fasc-button fasc-size-medium fasc-type-flat fasc-rounded-medium" style="background-color: #33809e; color: #ffffff;" target="_blank" rel="noopener noreferrer" href="http://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/">Android Barcode Tutorial</a></p>



<h3 class="wp-block-heading">2. Optical Character Recognition (OCR)&nbsp;on Android</h3>



<p class="wp-block-paragraph">Mobile Vision Text API is another great feature packed into this library. Its purpose is straight forward, i.e. text recognition in an image or a stream of frames.&nbsp;It can recognize a majority of Latin character based languages like English, French, Italian Dutch etc. Therefore if your app needs to extract text out of an image, this is the perfect solution&nbsp;for you. As once its dependencies are downloaded, you no more required to have an internet connection, all the character recognition takes place on device itself.</p>



<p class="wp-block-paragraph">Incase you wonder; how would this Android Mobile Vision Text API deliver large results, as when scanning a page of a book- a lot of words could be scanned. But thankfully this API returns text in a structured way. It mainly divides text into three sections:</p>



<ol class="wp-block-list"><li><strong>Block</strong>: Top level structure, contains all the paragraphs.</li><li><strong>Line</strong>: Mid level structure, contains lines in a block.</li><li><strong>Word</strong>: Low level structure, contains a single word from line.</li></ol>



<p class="wp-block-paragraph">To learn more about the Text API, please refer to this tutorial:</p>



<p class="wp-block-paragraph" style="text-align:center"><a class="fasc-button fasc-size-medium fasc-type-flat fasc-rounded-medium" style="background-color: #33809e; color: #ffffff;" target="_blank" rel="noopener noreferrer" href="http://www.truiton.com/2016/11/optical-character-recognition-android-ocr/">Android OCR Tutorial</a></p>



<h3 class="wp-block-heading">3. Face Detection&nbsp;on Android</h3>



<p class="wp-block-paragraph">This is the most powerful API in&nbsp;all, as it has human&nbsp;Face Detection capabilities.&nbsp;It is a perfectly suited API for any face filter or camera app, as it performs the analysis on the device itself once the package is downloaded. Interestingly it not only recognizes a face but can also extract the facial features of that face, including eyes nose and mouth etc. Since this API as of now does not support face recognition it cannot identify similarity between two faces, but can still classify the features like, if the eyes are open or not. The functionalities that Mobile Vision Face Detection API supports are:</p>



<ol class="wp-block-list"><li><strong>Landmark Detection:</strong> Face API understands the human face in terms of landmarks.&nbsp;When a face is scanned via this API, it identifies that face via landmarks. In simple terms face landmarks are: nose, mouth, left eye, and right eye etc. By using this API you can actually extract the position of all these landmarks.&nbsp;</li><li><strong>Classification:</strong> This API not only scans a face but can also apply some basic logic and identify certain characteristics on the scanned face. For ex. with this feature we can find out whether the face has its eyes open or not. Also we can find out the probability of a smile on that face.&nbsp;</li><li><strong>Tracking:</strong> This is the most interesting feature of this API, you can actually track a face in a video sequence through this API. This feature of Mobile Vision API can be used to identify and track a face in a video. Once again this is not an application of face recognition, instead it tracks the face through movement of that particular face in the video.&nbsp;</li></ol>



<p class="wp-block-paragraph">To learn more in detail about Face Detection, please refer to this tutorial:</p>



<p class="wp-block-paragraph" style="text-align:center"><a class="fasc-button fasc-size-medium fasc-type-flat fasc-rounded-medium" style="background-color: #33809e; color: #ffffff;" target="_blank" rel="noopener noreferrer" href="http://www.truiton.com/2017/05/android-face-detection-example/">Face Detection Tutorial</a>&nbsp;</p>



<h2 class="wp-block-heading">Tracking Faces, Bar codes&nbsp;and QR Codes Simultaneously</h2>



<p class="wp-block-paragraph">Interestingly, if you want to scan and track multiple faces simultaneously, even that is possible through this API. All you need to do is initialize a <a href="https://developers.google.com/android/reference/com/google/android/gms/vision/MultiProcessor" target="_blank" rel="noopener noreferrer">MultiProcessor</a> and track multiple faces through this API. Also if you want to track multiple Bar codes or QR codes, same thing is applicable, as all of this is a part of <a href="http://www.truiton.com/2017/05/introducing-android-mobile-vision-api/">Mobile Vision API</a>, backed by Google Play Services. But even more interesting thing is that you can track Bar codes, QR codes and Faces in a single frame, by using the <a href="https://developers.google.com/android/reference/com/google/android/gms/vision/MultiDetector" target="_blank" rel="noopener noreferrer">MultiDetector</a> class of the same API suite. This makes the mobile vision APIs an outstanding leader in terms of features when compared to any other such library in the market. As its light, easy to integrate and very easy to use. For more updates, please connect with us on Twitter, Facebook and Google+.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/">Introducing Android Mobile Vision API</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2017/05/introducing-android-mobile-vision-api/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1557</post-id>	</item>
		<item>
		<title>Optical Character Recognition on Android &#8211; OCR</title>
		<link>https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/</link>
					<comments>https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Sun, 06 Nov 2016 15:12:47 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Image Recognition]]></category>
		<category><![CDATA[Mobile Vision API]]></category>
		<category><![CDATA[OCR]]></category>
		<guid isPermaLink="false">http://www.truiton.com/?p=1606</guid>

					<description><![CDATA[<p>Android itself is a smart OS, still it lacked a very basic feature of text recognition. But not anymore; with the official Optical Character Recognition API of Android and the Mobile Vision library, now Android can perform OCR very efficiently and correctly. I did a very basic feature test to have a look at the&#8230;&#160;<a href="https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Optical Character Recognition on Android &#8211; OCR</span></a></p>
<p>The post <a href="https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/">Optical Character Recognition on Android &#8211; OCR</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" decoding="async" width="950" height="530" data-attachment-id="1612" data-permalink="https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/android-ocr-library-featured/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?fit=950%2C530&amp;ssl=1" data-orig-size="950,530" data-comments-opened="1" data-image-title="android-ocr-library-featured" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?fit=950%2C530&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?resize=950%2C530" alt="android ocr library - featured" class="wp-image-1612" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?w=950&amp;ssl=1 950w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?resize=600%2C335&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?resize=300%2C167&amp;ssl=1 300w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-Featured.jpg?resize=768%2C428&amp;ssl=1 768w" sizes="(max-width: 950px) 100vw, 950px" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Android itself is a smart OS, still it lacked a very basic feature of text recognition. But not anymore; with the official Optical Character Recognition API of Android and the Mobile Vision library, now Android can perform OCR very efficiently and correctly. I did a very basic feature test to have a look at the new functionality and found out its very fast and easy to use. Here in this Optical Character Recognition(OCR) example of Android, I would simply import the library, click a picture of a piece of text and look for text blocks in it. But before doing so lets take an overview of Android Mobile Vision API to understand the working of Text API better.</p>



<h2 class="wp-block-heading">Android Mobile Vision Library</h2>



<p class="wp-block-paragraph">Consider a scenario where you wish to scan&nbsp;and an image or a video stream and&nbsp;detect&nbsp;faces, barcodes, QR codes or Text in&nbsp;it on Android. Astonishingly till now no such framework existed on Android. But now Google has introduced <a href="https://developers.google.com/vision/" target="_blank" rel="noopener noreferrer">Mobile Vision APIs</a>. These set of APIs&nbsp;provide a very easy to use programming interfaces through which we can scan Faces, Barcodes, QR Codes and Text without writing huge amount of code.&nbsp;And the best part is that these can be used offline as well, i.e. only once when the app is downloaded the required dependencies are downloaded, post that an internet connection is not required any more. As this feature is introduced on Android through the Google Play services.&nbsp;To enable your app to use Mobile Vision APIs, you need to add this dependency in your <code>build.gradle</code> file:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">compile 'com.google.android.gms:play-services-vision:11.4.0'</pre>



<p class="wp-block-paragraph">Please Note: Learn more on how to <a href="https://developers.google.com/android/guides/setup" target="_blank" rel="noopener noreferrer">setup Google Play Services</a>. Or learn more about <a href="http://www.truiton.com/2017/05/introducing-android-mobile-vision-api/">Mobile Vision API</a>.</p>



<h2 class="wp-block-heading">Introducing an Android OCR Library &#8211; Text Recognition API</h2>



<p class="wp-block-paragraph">Since the Android OS was brought on to production devices, Optical Character Recognition has been a common area of research. But this <a href="https://developers.google.com/vision/text-overview" target="_blank" rel="noopener noreferrer">Text Recognition API</a> of Mobile Vision suite would bring all these researches to a stop. As this Google powered API contains&nbsp;features like multiple language recognition where languages are like : English, French, German, Spanish or&nbsp;any other Latin based text. Also the text can be parsed from a stream of frames i.e. a video and displayed on the screen in real time as displayed in the image above. But due to the scope of this Android OCR Library example we would keep things simple and scan the text from an image only, as this tutorial is targeted for beginners. Apart from this the interesting part is, all this is done offline by the Google Play services itself, i.e. no internet connection is required after once it has been set up in the app (shown in steps ahead). &nbsp;Now when it comes to structuring the text,&nbsp;this&nbsp;Android OCR library not only recognizes the text but can also divide the&nbsp;captured text into the following categories:</p>



<ol class="wp-block-list"><li>Block &#8211;&nbsp;<code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/text/TextBlock" target="_blank" rel="noopener noreferrer">TextBlock</a> &#8211; A top level object where a scanned paragraph or column is&nbsp;captured.</li><li>Line &#8211; <code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/text/Line" target="_blank" rel="noopener noreferrer">Line</a> &#8211; A line of text captured from a block of text.</li><li>Word &#8211; <code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/text/Element" target="_blank" rel="noopener noreferrer">Element</a> &#8211; A single word recognized in a <code>Line</code>.</li></ol>



<h2 class="wp-block-heading">Android OCR Example</h2>



<p class="wp-block-paragraph">Now that we have a basic understanding of Android OCR library, particularly the Text Recognition API. I will demonstrate by an example where we would simply take a picture and scan for text in it. Now as a thumb rule to do so first we may need to set up our Android app to download the play services dependency for&nbsp;Optical Character Recognition. Therefore please&nbsp;include the block of code below in your manifest&nbsp;to instruct installer to download the OCR dependency at the time of installing the app.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;meta-data
            android:name="com.google.android.gms.vision.DEPENDENCIES"
            android:value="ocr"/></pre>



<p class="wp-block-paragraph"><span style="text-decoration: underline;">Please Note:</span> <em>This is not a mandatory step, but helps in downloading the dependencies beforehand. Also the link to full source code is at the end of this tutorial.</em></p>



<p class="wp-block-paragraph">Next lets define a layout to display the scanned results:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;android.support.constraint.ConstraintLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.truiton.mobile.vision.ocr.MainActivity">

    &lt;ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/truiton"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1"/>

    &lt;Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:text="Scan Text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1"
        />

    &lt;TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp"
        android:text="Scan Results:"
        android:textAllCaps="false"
        android:textStyle="normal|bold"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1"/>

    &lt;ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        tools:layout_constraintTop_creator="1"
        tools:layout_constraintRight_creator="1"
        tools:layout_constraintBottom_creator="1"
        tools:layout_constraintLeft_creator="1">

        &lt;LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            &lt;TextView
                android:id="@+id/results"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1"/>
        &lt;/LinearLayout>
    &lt;/ScrollView>
&lt;/android.support.constraint.ConstraintLayout>
</pre>



<p class="wp-block-paragraph">I was playing around with <code><code></code></code><a href="https://developer.android.com/training/constraint-layout/index.html" target="_blank" rel="noopener noreferrer">ConstraintLayout</a> in Android. Hence made it in Constraint layout, although its not a requirement to use <code>ConstraintLayout</code> for this Android OCR Library example. The above layout basically contains a <code>ScrollView</code> to accurately display the scanned text. Next lets define the main Activity:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.mobile.vision.ocr;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.text.Text;
import com.google.android.gms.vision.text.TextBlock;
import com.google.android.gms.vision.text.TextRecognizer;

import java.io.File;
import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {
    private static final String LOG_TAG = "Text API";
    private static final int PHOTO_REQUEST = 10;
    private TextView scanResults;
    private Uri imageUri;
    private TextRecognizer detector;
    private static final int REQUEST_WRITE_PERMISSION = 20;
    private static final String SAVED_INSTANCE_URI = "uri";
    private static final String SAVED_INSTANCE_RESULT = "result";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        scanResults = (TextView) findViewById(R.id.results);
        if (savedInstanceState != null) {
            imageUri = Uri.parse(savedInstanceState.getString(SAVED_INSTANCE_URI));
            scanResults.setText(savedInstanceState.getString(SAVED_INSTANCE_RESULT));
        }
        detector = new TextRecognizer.Builder(getApplicationContext()).build();
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ActivityCompat.requestPermissions(MainActivity.this, new
                        String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_WRITE_PERMISSION:
                if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    takePicture();
                } else {
                    Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
                }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PHOTO_REQUEST &amp;&amp; resultCode == RESULT_OK) {
            launchMediaScanIntent();
            try {
                Bitmap bitmap = decodeBitmapUri(this, imageUri);
                if (detector.isOperational() &amp;&amp; bitmap != null) {
                    Frame frame = new Frame.Builder().setBitmap(bitmap).build();
                    SparseArray&lt;TextBlock&gt; textBlocks = detector.detect(frame);
                    String blocks = "";
                    String lines = "";
                    String words = "";
                    for (int index = 0; index &lt; textBlocks.size(); index++) {
                        //extract scanned text blocks here
                        TextBlock tBlock = textBlocks.valueAt(index);
                        blocks = blocks + tBlock.getValue() + "\n" + "\n";
                        for (Text line : tBlock.getComponents()) {
                            //extract scanned text lines here
                            lines = lines + line.getValue() + "\n";
                            for (Text element : line.getComponents()) {
                                //extract scanned text words here
                                words = words + element.getValue() + ", ";
                            }
                        }
                    }
                    if (textBlocks.size() == 0) {
                        scanResults.setText("Scan Failed: Found nothing to scan");
                    } else {
                        scanResults.setText(scanResults.getText() + "Blocks: " + "\n");
                        scanResults.setText(scanResults.getText() + blocks + "\n");
                        scanResults.setText(scanResults.getText() + "---------" + "\n");
                        scanResults.setText(scanResults.getText() + "Lines: " + "\n");
                        scanResults.setText(scanResults.getText() + lines + "\n");
                        scanResults.setText(scanResults.getText() + "---------" + "\n");
                        scanResults.setText(scanResults.getText() + "Words: " + "\n");
                        scanResults.setText(scanResults.getText() + words + "\n");
                        scanResults.setText(scanResults.getText() + "---------" + "\n");
                    }
                } else {
                    scanResults.setText("Could not set up the detector!");
                }
            } catch (Exception e) {
                Toast.makeText(this, "Failed to load Image", Toast.LENGTH_SHORT)
                        .show();
                Log.e(LOG_TAG, e.toString());
            }
        }
    }

    private void takePicture() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File photo = new File(Environment.getExternalStorageDirectory(), "picture.jpg");
        imageUri = FileProvider.getUriForFile(MainActivity.this,
                BuildConfig.APPLICATION_ID + ".provider", photo);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intent, PHOTO_REQUEST);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if (imageUri != null) {
            outState.putString(SAVED_INSTANCE_URI, imageUri.toString());
            outState.putString(SAVED_INSTANCE_RESULT, scanResults.getText().toString());
        }
        super.onSaveInstanceState(outState);
    }

    private void launchMediaScanIntent() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(imageUri);
        this.sendBroadcast(mediaScanIntent);
    }

    private Bitmap decodeBitmapUri(Context ctx, Uri uri) throws FileNotFoundException {
        int targetW = 600;
        int targetH = 600;
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(ctx.getContentResolver().openInputStream(uri), null, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;

        return BitmapFactory.decodeStream(ctx.getContentResolver()
                .openInputStream(uri), null, bmOptions);
    }
}
</pre>



<p class="wp-block-paragraph">In the above piece of code, I simply initialized&nbsp;a <code>TextRecognizer</code> and asked the user to grant the permission to store the captured image on disk. Post which, when an image like shown below is captured, we resize the image in method&nbsp;<code>decodeBitmapUri</code> to a smaller size so that, it can be scanned faster. Once the image is scaled, we check for operational&nbsp;<code>TextRecognizer</code>. Then after the detector is operational, we scan out the text from picture.</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="800" height="448" data-attachment-id="1616" data-permalink="https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/android-ocr-library-1/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?fit=800%2C448&amp;ssl=1" data-orig-size="800,448" data-comments-opened="1" data-image-title="android-ocr-library-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?fit=800%2C448&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?resize=800%2C448" alt="android ocr library" class="wp-image-1616" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?w=800&amp;ssl=1 800w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?resize=600%2C336&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?resize=300%2C168&amp;ssl=1 300w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-1.png?resize=768%2C430&amp;ssl=1 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></figure></div>



<p class="wp-block-paragraph">When the Android OCR library &#8211; the Mobile Vision, returned the text from the picture above, it was very accurate. Have a look at the result below:</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="272" height="480" data-attachment-id="1617" data-permalink="https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/android-ocr-library-2/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-2.gif?fit=272%2C480&amp;ssl=1" data-orig-size="272,480" data-comments-opened="1" data-image-title="android-ocr-library-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-2.gif?fit=272%2C480&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/11/Android-OCR-Library-2.gif?resize=272%2C480" alt="android ocr library " class="wp-image-1617"/></figure></div>



<p class="wp-block-paragraph">For full source code, please refer to the link below:</p>



<p class="wp-block-paragraph" style="text-align:center"><a class="fasc-button fasc-size-large fasc-type-flat fasc-rounded-medium ico-fa fasc-ico-before fa-github" style="background-color: #0364af; color: #ffffff;" target="_blank" rel="noopener noreferrer" href="https://github.com/Truiton/MobileVisionAPI/tree/master/OCRSample">Full Source Code</a></p>



<p class="wp-block-paragraph">Hence I believe this is one of the best OCR libraries available for Android till date. As it gives the unique capability of offline text scanning, without compromising on&nbsp;quality.&nbsp;Therefore if you have to make an app where it is required to scan the text and process it, use the Text API of Mobile Vision for Optical Character Recognition. For more posts like this, please connect with us on Twitter, Facebook and Google+. Hope this helped.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/">Optical Character Recognition on Android &#8211; OCR</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2016/11/optical-character-recognition-android-ocr/feed/</wfw:commentRss>
			<slash:comments>16</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1606</post-id>	</item>
		<item>
		<title>Android Example &#8211; Programmatically Scan QR Code and Bar Code</title>
		<link>https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/</link>
					<comments>https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Mon, 26 Sep 2016 16:25:53 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Image Recognition]]></category>
		<category><![CDATA[Mobile Vision API]]></category>
		<guid isPermaLink="false">http://www.truiton.com/?p=1572</guid>

					<description><![CDATA[<p>Often when building Android apps, we encounter situations where it is required to scan a bar code or QR code. Now as difficult as it sounds, the complex code it has if you plan to write your own scanning algorithm. But this is the place where new and improved Mobile Vision&#160;from&#160;Google&#160;steps in. This API was&#8230;&#160;<a href="https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Android Example &#8211; Programmatically Scan QR Code and Bar Code</span></a></p>
<p>The post <a href="https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/">Android Example &#8211; Programmatically Scan QR Code and Bar Code</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="950" height="530" data-attachment-id="1587" data-permalink="https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/android-scan-qr-code-example-featured/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?fit=950%2C530&amp;ssl=1" data-orig-size="950,530" data-comments-opened="1" data-image-title="Android Scan QR Code Example" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?fit=950%2C530&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?resize=950%2C530" alt="Android Scan QR Code Example" class="wp-image-1587" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?w=950&amp;ssl=1 950w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?resize=600%2C335&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?resize=300%2C167&amp;ssl=1 300w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/android-scan-qr-code-example-Featured.jpg?resize=768%2C428&amp;ssl=1 768w" sizes="auto, (max-width: 950px) 100vw, 950px" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Often when building Android apps, we encounter situations where it is required to scan a bar code or QR code. Now as difficult as it sounds, the complex code it has if you plan to write your own scanning algorithm. But this is the place where new and improved <a href="https://developers.google.com/vision/" target="_blank" rel="noopener noreferrer">Mobile Vision</a>&nbsp;from&nbsp;Google&nbsp;steps in. This API was initially introduced in August 2015, but now it as been further improved and re-introduced&nbsp;including features like OCR and object tracking along with the existing features of scanning qr code and barcodes. Therefore here lets understand the usage of Google&#8217;s&nbsp;Mobile Vision with an example&nbsp;where we scan a QR code&nbsp;on Android.</p>



<p class="wp-block-paragraph">Programmatically scanning a QR Code or&nbsp;Bar Code on Android has always been a topic of great discussion. There are many ways through which this can be done:</p>



<ul class="wp-block-list"><li>Using a web based API&nbsp;solution, where image is uploaded to a server and it returns back the results.</li><li>Use a hybrid solution where web based app accesses your camera and scans Bar Code or QR Code.</li><li>Write your own image scanning algorithm.</li><li>Use the Google Play Services integrated Mobile Vision.</li></ul>



<p class="wp-block-paragraph">In my opinion&nbsp;using the Android&nbsp;Mobile Vision for scanning QR codes is the most favorable option in comparison to other options&nbsp;because it offers&nbsp;offline scanning of images, resulting a fast scan and an immediate result. This being said its also the easiest option available. As it just requires a few lines of code to make it work. Besides that;&nbsp;when using this library,&nbsp;you don&#8217;t need to import any other&nbsp;android scanning library as this&nbsp;API also takes care of&nbsp;OCR and facial scanning. To read more about it please visit my article&nbsp;on Android Mobile Vision API <em>(coming soon)</em>.</p>



<h2 class="wp-block-heading">Introducing the Official Android QR and Barcode Scanning Library : Mobile Vision</h2>



<p class="wp-block-paragraph">There are many third party libraries available for parsing of barcodes and QR codes, some of them are even endorsed by Google I believe. But nowdays&nbsp;reading of QR codes and barcodes on Android has become so common that, it demanded an official solution. Hence the Mobile Vision APIs were introduced with QR code and barcode scanning capabilities for Android. While most of the opensource&nbsp;libraries scan only one QR code or barcode at a time. These Mobile Vision APIs can scan multiple QR codes at the same time. Also if you want, you can directly integrate them&nbsp;with android&#8217;s&nbsp;camera and scan for barcodes and QR codes on the fly while streaming on a surface.</p>



<p class="wp-block-paragraph">As of now Mobile Vision APIs can scan following types of Bar codes and QR codes on Android:</p>



<ul class="wp-block-list"><li>1D barcodes: <a href="https://en.wikipedia.org/wiki/International_Article_Number_(EAN)" target="_blank" rel="noopener noreferrer">EAN-13, EAN-8</a>, <a href="https://en.wikipedia.org/wiki/Universal_Product_Code" target="_blank" rel="noopener noreferrer">UPC-A, UPC-E</a>, <a href="https://en.wikipedia.org/wiki/Code_39" target="_blank" rel="noopener noreferrer">Code-39</a>, <a href="https://en.wikipedia.org/wiki/Code_93" target="_blank" rel="noopener noreferrer">Code-93</a>, <a href="https://en.wikipedia.org/wiki/Code_128" target="_blank" rel="noopener noreferrer">Code-128</a>, <a href="https://en.wikipedia.org/wiki/Interleaved_2_of_5" target="_blank" rel="noopener noreferrer">ITF</a>, <a href="https://en.wikipedia.org/wiki/Codabar" target="_blank" rel="noopener noreferrer">Codabar</a></li><li>2D barcodes: <a href="https://en.wikipedia.org/wiki/QR_code" target="_blank" rel="noopener noreferrer">QR Code</a>, <a href="https://en.wikipedia.org/wiki/Data_Matrix" target="_blank" rel="noopener noreferrer">Data Matrix</a>, <a href="https://en.wikipedia.org/wiki/PDF417" target="_blank" rel="noopener noreferrer">PDF-417</a>, <a href="https://en.wikipedia.org/wiki/PDF417" target="_blank" rel="noopener noreferrer">AZTEC</a></li></ul>



<h2 class="wp-block-heading">&nbsp;</h2>



<h2 class="wp-block-heading">Setting up Android QR Code Scan Library : Mobile Vision</h2>



<p class="wp-block-paragraph">As I have mentioned before, setting up Mobile Vision API is very easy, all of its downloads are managed internally by Google Play services. Although to properly integrate it and make it functional before the actual usage, it is advised to reference the used features of Mobile Vision API in the Manifest of your app. This way the dependencies are downloaded before you can actually use them i.e. at the time of installation. Also please don&#8217;t forget to follow the steps for <a href="https://developers.google.com/android/guides/setup" target="_blank" rel="noopener noreferrer">Google Play Services Integration</a>. But in our case we only need to compile&nbsp;<code>com.google.android.gms:play-services-vision</code>, therefore make sure your build.gradle (app) has following dependencies:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:26.1.0'
    compile 'com.google.android.gms:play-services-vision:11.4.0'
}</pre>



<p class="wp-block-paragraph">And build.gradle(global) should have this:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">allprojects {
    repositories {
        jcenter()
        maven {
            url "https://maven.google.com"
        }
    }
}</pre>



<p class="wp-block-paragraph">Also as mentioned to make Mobile Vision APIs functional for an&nbsp;Android Scan QR&nbsp;Code Example before installation, please include these lines in your Manifest inside the application tag:</p>



<pre class="wp-block-preformatted lang:xhtml decode:true">&lt;meta-data
            android:name="com.google.android.gms.vision.DEPENDENCIES"
            android:value="barcode"/&gt;</pre>



<p class="wp-block-paragraph">Here the <code>android:value</code> tag can have following comma separated values:</p>



<ul class="wp-block-list"><li>barcode</li><li>face</li><li>ocr</li></ul>



<h2 class="wp-block-heading">Android Scan QR Code Example</h2>



<p class="wp-block-paragraph">One of the interesting features of Mobile Vision API is that it performs a scan very fast. Also its documentation states that you can perform&nbsp;multiple types of scans on the&nbsp;same frame. This means&nbsp;you can scan multiple barcodes, QR Codes and faces together. Be it a video, a picture, or a video stream. But covering all of this in a single article is not possible. Therefore to&nbsp;start off we will build a basic example where we would use native phone&#8217;s camera to take a picture and scan it for barcodes and qr codes, and building&nbsp;a basic Android Scan QR code Example.</p>



<p class="wp-block-paragraph">To start off, have a look at the Manifest, where we define the camera and barcode dependency for this <a href="http://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/">Android Scan QR Code example</a>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;manifest package="com.truiton.mobile.vision.qrcode"
          xmlns:android="http://schemas.android.com/apk/res/android">

    &lt;uses-feature
        android:name="android.hardware.camera"
        android:required="true"/>
    &lt;uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    &lt;application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        &lt;meta-data
            android:name="com.google.android.gms.vision.DEPENDENCIES"
            android:value="barcode"/>
        &lt;activity android:name=".MainActivity">
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN"/>

                &lt;category android:name="android.intent.category.LAUNCHER"/>
            &lt;/intent-filter>
        &lt;/activity>
        &lt;provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            &lt;meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        &lt;/provider>
    &lt;/application>

&lt;/manifest></pre>



<p class="wp-block-paragraph"><em><strong>Please Note:</strong> full source code is available at the end of the tutorial.</em></p>



<p class="wp-block-paragraph">Next lets define a basic layout to show the QR code scan results.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.truiton.mobile.vision.qrcode.MainActivity">

    &lt;ImageView
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerHorizontal="true"
        android:src="@mipmap/truiton"/>

    &lt;TextView
        android:id="@+id/scan_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/image"
        android:layout_centerHorizontal="true"
        android:text="Scan Results:"
        android:textStyle="bold"/>

    &lt;TextView
        android:id="@+id/scan_results"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/scan_header"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"/>

    &lt;Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="20dp"
        android:text="Take Picture"/>

&lt;/RelativeLayout>
</pre>



<p class="wp-block-paragraph">Now lets define the main activity where the Android QR/Bar code scanning takes place:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.mobile.vision.qrcode;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;

import java.io.File;
import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {
    private static final String LOG_TAG = "Barcode Scanner API";
    private static final int PHOTO_REQUEST = 10;
    private TextView scanResults;
    private BarcodeDetector detector;
    private Uri imageUri;
    private static final int REQUEST_WRITE_PERMISSION = 20;
    private static final String SAVED_INSTANCE_URI = "uri";
    private static final String SAVED_INSTANCE_RESULT = "result";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        scanResults = (TextView) findViewById(R.id.scan_results);
        if (savedInstanceState != null) {
            imageUri = Uri.parse(savedInstanceState.getString(SAVED_INSTANCE_URI));
            scanResults.setText(savedInstanceState.getString(SAVED_INSTANCE_RESULT));
        }
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ActivityCompat.requestPermissions(MainActivity.this, new
                        String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
            }
        });

        detector = new BarcodeDetector.Builder(getApplicationContext())
                .setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
                .build();
        if (!detector.isOperational()) {
            scanResults.setText("Could not set up the detector!");
            return;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_WRITE_PERMISSION:
                if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    takePicture();
                } else {
                    Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
                }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PHOTO_REQUEST &amp;&amp; resultCode == RESULT_OK) {
            launchMediaScanIntent();
            try {
                Bitmap bitmap = decodeBitmapUri(this, imageUri);
                if (detector.isOperational() &amp;&amp; bitmap != null) {
                    Frame frame = new Frame.Builder().setBitmap(bitmap).build();
                    SparseArray&lt;Barcode&gt; barcodes = detector.detect(frame);
                    for (int index = 0; index &lt; barcodes.size(); index++) {
                        Barcode code = barcodes.valueAt(index);
                        scanResults.setText(scanResults.getText() + code.displayValue + "\n");

                        //Required only if you need to extract the type of barcode
                        int type = barcodes.valueAt(index).valueFormat;
                        switch (type) {
                            case Barcode.CONTACT_INFO:
                                Log.i(LOG_TAG, code.contactInfo.title);
                                break;
                            case Barcode.EMAIL:
                                Log.i(LOG_TAG, code.email.address);
                                break;
                            case Barcode.ISBN:
                                Log.i(LOG_TAG, code.rawValue);
                                break;
                            case Barcode.PHONE:
                                Log.i(LOG_TAG, code.phone.number);
                                break;
                            case Barcode.PRODUCT:
                                Log.i(LOG_TAG, code.rawValue);
                                break;
                            case Barcode.SMS:
                                Log.i(LOG_TAG, code.sms.message);
                                break;
                            case Barcode.TEXT:
                                Log.i(LOG_TAG, code.rawValue);
                                break;
                            case Barcode.URL:
                                Log.i(LOG_TAG, "url: " + code.url.url);
                                break;
                            case Barcode.WIFI:
                                Log.i(LOG_TAG, code.wifi.ssid);
                                break;
                            case Barcode.GEO:
                                Log.i(LOG_TAG, code.geoPoint.lat + ":" + code.geoPoint.lng);
                                break;
                            case Barcode.CALENDAR_EVENT:
                                Log.i(LOG_TAG, code.calendarEvent.description);
                                break;
                            case Barcode.DRIVER_LICENSE:
                                Log.i(LOG_TAG, code.driverLicense.licenseNumber);
                                break;
                            default:
                                Log.i(LOG_TAG, code.rawValue);
                                break;
                        }
                    }
                    if (barcodes.size() == 0) {
                        scanResults.setText("Scan Failed: Found nothing to scan");
                    }
                } else {
                    scanResults.setText("Could not set up the detector!");
                }
            } catch (Exception e) {
                Toast.makeText(this, "Failed to load Image", Toast.LENGTH_SHORT)
                        .show();
                Log.e(LOG_TAG, e.toString());
            }
        }
    }

    private void takePicture() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File photo = new File(Environment.getExternalStorageDirectory(), "picture.jpg");
        imageUri = FileProvider.getUriForFile(MainActivity.this,
                BuildConfig.APPLICATION_ID + ".provider", photo);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intent, PHOTO_REQUEST);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if (imageUri != null) {
            outState.putString(SAVED_INSTANCE_URI, imageUri.toString());
            outState.putString(SAVED_INSTANCE_RESULT, scanResults.getText().toString());
        }
        super.onSaveInstanceState(outState);
    }

    private void launchMediaScanIntent() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(imageUri);
        this.sendBroadcast(mediaScanIntent);
    }

    private Bitmap decodeBitmapUri(Context ctx, Uri uri) throws FileNotFoundException {
        int targetW = 600;
        int targetH = 600;
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(ctx.getContentResolver().openInputStream(uri), null, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;

        return BitmapFactory.decodeStream(ctx.getContentResolver()
                .openInputStream(uri), null, bmOptions);
    }
}
</pre>



<p class="wp-block-paragraph"><em><span style="text-decoration: underline;">Please Note:</span> Images to be scanned, should not be too big.</em></p>



<p class="wp-block-paragraph">When it comes to scanning of QR code from a picture on an Android app&nbsp;using the Mobile Vision APIs, the process is quite simple. All we need to do is, pass on a <code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/Frame" target="_blank" rel="noopener noreferrer">Frame</a> to the <code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/barcode/BarcodeDetector" target="_blank" rel="noopener noreferrer">BarcodeDetector</a>, this will return an array of type <code><code></code></code><a href="https://developers.google.com/android/reference/com/google/android/gms/vision/barcode/Barcode" target="_blank" rel="noopener noreferrer">Barcode</a>, which would contain the actual barcode value. But&nbsp;there are prerequisites to this implementation, like declaring all permissions and getting&nbsp;them on run time, which is shown in the&nbsp;android scan qr code example above. To view full source code for this example please refer to the link below:</p>



<p class="wp-block-paragraph" style="text-align:center"><a class="fasc-button fasc-size-large fasc-type-flat fasc-rounded-medium ico-fa fasc-ico-before fa-github" style="background-color: #0364af; color: #ffffff;" target="_blank" rel="noopener noreferrer" href="https://github.com/Truiton/MobileVisionAPI/tree/master/QRCode">Full Source Code</a></p>



<p class="wp-block-paragraph">Also please have a look at the screens for this&nbsp;Android Scan QR&nbsp;code&nbsp;scan example:</p>



<ul data-carousel-extra='{&quot;blog_id&quot;:1,&quot;permalink&quot;:&quot;https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/&quot;}'  class="wp-block-gallery columns-3 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><a href="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="883" data-attachment-id="1588" data-permalink="https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/android-scan-qr-code-example-1/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?fit=500%2C883&amp;ssl=1" data-orig-size="500,883" data-comments-opened="1" data-image-title="android-scan-qr-code-example-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?fit=500%2C883&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?resize=500%2C883&#038;ssl=1" alt="Android QR Code Detection -1" data-id="1588" class="wp-image-1588" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?w=500&amp;ssl=1 500w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?resize=170%2C300&amp;ssl=1 170w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-1.png?resize=300%2C530&amp;ssl=1 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /></a></figure></li><li class="blocks-gallery-item"><figure><a href="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" width="700" height="331" data-attachment-id="1589" data-permalink="https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/android-scan-qr-code-example-2/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?fit=700%2C331&amp;ssl=1" data-orig-size="700,331" data-comments-opened="1" data-image-title="android-scan-qr-code-example-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?fit=700%2C331&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?resize=700%2C331&#038;ssl=1" alt="" data-id="1589" class="wp-image-1589" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?w=700&amp;ssl=1 700w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?resize=600%2C284&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/09/Android-Scan-QR-Code-Example-2.png?resize=300%2C142&amp;ssl=1 300w" sizes="auto, (max-width: 700px) 100vw, 700px" /></a></figure></li></ul>



<p class="wp-block-paragraph">By using these Mobile Vision APIs for barcodes and QR codes, we can also determine the type of barcode or QR code is being scanned. This is one of the most interesting parts about this API, it reads the data, as well as it understands what type of data it is. For e.g. when an event QR code is scanned, we can use <a href="https://developers.google.com/android/reference/com/google/android/gms/vision/barcode/Barcode.CalendarEvent" target="_blank" rel="noopener noreferrer">Barcode.CalendarEvent</a> class to extract out the exact data in required format. This&nbsp;can help us in reducing our code bases very efficiently.</p>



<p class="wp-block-paragraph">When speaking of Android&nbsp;Barcode scanning libraries, Mobile Vision API is the latest addition in the list. Also it is one of the most stable and reliable options as its a library provided by Google, through play services. Which definitely&nbsp;gives it an added advantage over other libraries. That being said, would like to say,&nbsp;we have finally succeeded in offline scanning of barcodes and QR Codes. As most of the methods require uploading of images to a server, or including huge code bases or libraries into our project for offline scanning. But with Mobile Vision APIs&nbsp;nothing of this sort needs to be done, as all this is taken care by Google Play Services once they are downloaded. Hope this helped you. Connect with us on Twitter, Facebook and Google+ for more updates.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/">Android Example &#8211; Programmatically Scan QR Code and Bar Code</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2016/09/android-example-programmatically-scan-qr-code-and-bar-code/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1572</post-id>	</item>
		<item>
		<title>Image Recognition on Andorid with Google Cloud Vision API</title>
		<link>https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/</link>
					<comments>https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Sun, 05 Jun 2016 07:10:17 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Google Cloud Vision API]]></category>
		<category><![CDATA[Image Recognition]]></category>
		<guid isPermaLink="false">http://www.truiton.com/?p=1508</guid>

					<description><![CDATA[<p>Google introduced a new API called the Google Cloud Vision API. This API has full&#160;potential to understand the contents of an image by using the Google&#8217;s machine learning platform and&#160;TensorFlow. It&#160;allows the API to process individual pieces of an image separately and return the results really fast in a unified format. Therefore in simple terms&#8230;&#160;<a href="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Image Recognition on Andorid with Google Cloud Vision API</span></a></p>
<p>The post <a href="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/">Image Recognition on Andorid with Google Cloud Vision API</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="950" height="530" data-attachment-id="1509" data-permalink="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/android-cloud-vision-api/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?fit=950%2C530&amp;ssl=1" data-orig-size="950,530" data-comments-opened="1" data-image-title="Android Cloud Vision API" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?fit=950%2C530&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?resize=950%2C530" alt="Andorid Image Recognition with Google Cloud Vision API" class="wp-image-1509" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?w=950&amp;ssl=1 950w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?resize=600%2C335&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?resize=300%2C167&amp;ssl=1 300w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API.jpg?resize=768%2C428&amp;ssl=1 768w" sizes="auto, (max-width: 950px) 100vw, 950px" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Google introduced a new API called the <a href="https://cloud.google.com/vision/" target="_blank" rel="noopener noreferrer">Google Cloud Vision API</a>. This API has full&nbsp;potential to understand the contents of an image by using the Google&#8217;s machine learning platform and&nbsp;<a href="http://www.tensorflow.org/" target="_blank" rel="noopener noreferrer">TensorFlow</a>. It&nbsp;allows the API to process individual pieces of an image separately and return the results really fast in a unified format. Therefore in simple terms now you can submit&nbsp;an image to the Google Cloud Vision API&nbsp;and find out what&#8217;s in the image. What&#8217;s more; is that, when making a request to process an image; Google gives us the capability to specify the types of analysis that should be performed&nbsp;on this image. For example, a&nbsp;simple object identification, landmark detection, facial detection, sentimental analysis and many&nbsp;more such analysis could be performed&nbsp;on an image. But what&#8217;s even more great is that, this API can also be integrated directly into the Android apps. Making Android image recognition very simple. Also this is another way, Google lets us perform image recognition on Android, powered by Google cloud platform. Imagine the power an end user can have through this API.</p>



<p class="wp-block-paragraph">The new Google Cloud Vision API is a multi-platform solution for image recognition, weather its an Android app, iOS app or cloud storage, this API is available for image analysis. As this Cloud Vision API has SDK support for Java, Go Lang, Node.js, Python, and more importantly JSON format.&nbsp;But here in this article we would mainly discuss&nbsp;on&nbsp;how to do image recognition on android. Therefore continuing on Java/Android, you might be aware that, there are many ways to perform android image recognition like OpenCV, OCR reading libraries and facial recognition APIs. But none of them are&nbsp;as accurate and light weight as this new Android Cloud Vision API as they require a huge amount of data to be present on the app beforehand to perform object matching. Which in turn increases the APK size and&nbsp;still result in in-accurate data. Also&nbsp;to use this new Android Cloud Vision API and perform all sorts of image analysis; no heavy gradle or project files are required to be included in your project. Just the basic&nbsp;<code>google-api-client-android</code>,&nbsp;<code>google-http-client-gson</code> and&nbsp;<code>google-api-services-vision</code>&nbsp;dependencies are required in your gradle&nbsp;for models. Read more about it in the next section:</p>



<h2 class="wp-block-heading">Enabling yourself to use Google Cloud Vision API on Android</h2>



<p class="wp-block-paragraph">To perform Android image recognition using the Google Cloud Vision API, we must first enable it from the <a href="https://console.cloud.google.com/flows/enableapi?apiid=vision.googleapis.com" target="_blank" rel="noopener noreferrer">Google Cloud Developer Console</a>,&nbsp;please follow the steps:</p>



<ol class="wp-block-list"><li>Create a project in <a title="Google Developers Console" href="https://console.cloud.google.com/" target="_blank" rel="noopener noreferrer">Google Cloud Console</a> or use an existing one.</li><li>Enable <a href="https://console.cloud.google.com/billing">Billing</a> for the project. if you have a new or un-used account you can start a free trial (It might ask your credit card info to validate your identity but not charge you).</li><li>Enable the Google Cloud Vision API using <a href="https://console.cloud.google.com/flows/enableapi?apiid=vision.googleapis.com">this link</a>. OR
<ul>
<li>Navigate to “API Manager” section from the hamburger menu.</li>
<li>Search and select “Google Cloud Vision API”.</li>
<li>Enable it.</li>
</ul>
</li><li>Then go to the credentials section from the side menu.</li><li>Click on credentials drop down menu and select OAuth Client ID.
<ul>
<li>Select Application Type as Android.</li>
<li>Add a suitable name&nbsp;like&nbsp;<em>Android client for Cloud Vision API</em></li>
<li>Enter your SHA1 fingerprint in the desired format. Using the mentioned command on screen or use this <a title="Obtaining SHA1 Fingerprint from Android Keystore" href="http://www.truiton.com/2015/04/obtaining-sha1-fingerprint-android-keystore/" target="_blank" rel="noopener noreferrer">SHA1 fingerprint tutorial</a> to get your fingerprint.</li>
<li>Enter the package name for your app, can be located in the <code>defaultConfig</code> block of your gradle.</li>
<li>Click on create.</li>
</ul>
</li><li>That&#8217;s it, you&#8217;re done.</li></ol>



<p class="wp-block-paragraph">If you are planning to access Google Cloud Vision API through some other platform you may need to create the credentials in a different manner. As when accessing this API on Android to perform image analysis, we need the end user&#8217;s consent that we are accessing their pictures. Although&nbsp;if you are planning to perform image recognition in background, like a server to server interaction. Then things should be handled differently. We may not need to generate an OAuth ID, instead a Service Account key may be required. But lets not discuss that here; as here in this tutorial our main focus is to perform; Android image recognition. Therefore before moving on to next section lets add the following dependencies in your app gradle, although at the end of this example full source code is available:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.google.android.gms:play-services-base:9.0.2'
    compile 'com.google.android.gms:play-services-auth:9.0.2'
    compile 'com.google.apis:google-api-services-vision:v1-rev16-1.22.0'
    compile ('com.google.api-client:google-api-client-android:1.22.0') {
        exclude module: 'httpclient'
    }
    compile ('com.google.http-client:google-http-client-gson:1.20.0') {
        exclude module: 'httpclient'
    }
}</pre>



<h2 class="wp-block-heading">Supported Image Analysis Techniques in Cloud Vision API on Android</h2>



<p class="wp-block-paragraph">In general Google Cloud Vision API support many types of image analysis techniques. Be it&nbsp;optical character recognition, landmark detection or a simple logo detection. Cloud vision API&nbsp;does it very accurately. Also the best part about this API is that; its cross platform and is available via API access, which&nbsp;results in&nbsp;very light weight applications.&nbsp;Also since this technology is comparatively new, there is a lot of scope for improvement. And while that&#8217;s happening behind the scenes we don&#8217;t need to worry about the changing code-base as basically its just an API call. Moving on lets have a look at the supported Android image recognition techniques.</p>



<h3 class="wp-block-heading">1. LABEL_DETECTION</h3>



<p class="wp-block-paragraph">One of the most basic types of techniques available in Android&nbsp;Cloud Vision API is the label detection. This allows the API to analyse image content and list out all the items contained in it individually. Have a look at the image I uploaded:</p>



<div class="wp-block-image wp-image-1513 size-full"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="805" data-attachment-id="1513" data-permalink="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/android-cloud-vision-api-1/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-1.png?fit=500%2C805&amp;ssl=1" data-orig-size="500,805" data-comments-opened="1" data-image-title="Android Cloud Vision API &amp;#8211; 1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-1.png?fit=500%2C805&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-1.png?resize=500%2C805" alt="Android Cloud Vision API - 1" class="wp-image-1513" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-1.png?w=500&amp;ssl=1 500w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-1.png?resize=186%2C300&amp;ssl=1 186w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-1.png?resize=300%2C483&amp;ssl=1 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /><figcaption>Labels: statue, monument, sculpture, etc. Landmarks: Albert Einstein Memorial</figcaption></figure></div>



<h3 class="wp-block-heading">2.&nbsp;TEXT_DETECTION</h3>



<p class="wp-block-paragraph">Another interesting type of image analysis technique in Google Cloud Vision API is this text detection feature. It allows us to extract out the text from an image. My personal opinion is that, this feature alone could turn out to be the torch bearer for whole Cloud Vision API suite.</p>



<div class="wp-block-image wp-image-1514 size-full"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="805" data-attachment-id="1514" data-permalink="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/android-cloud-vision-api-2/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-2.png?fit=500%2C805&amp;ssl=1" data-orig-size="500,805" data-comments-opened="1" data-image-title="Android Cloud Vision API &amp;#8211; 2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-2.png?fit=500%2C805&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-2.png?resize=500%2C805" alt="Android Cloud Vision API - 2" class="wp-image-1514" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-2.png?w=500&amp;ssl=1 500w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-2.png?resize=186%2C300&amp;ssl=1 186w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Cloud-Vision-API-2.png?resize=300%2C483&amp;ssl=1 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /><figcaption>Texts: Federal Deposit Insurance Corporation, along with locale and formatting.</figcaption></figure></div>



<h3 class="wp-block-heading">3.&nbsp;LANDMARK_DETECTION</h3>



<p class="wp-block-paragraph">Google has gathered so much of data that now they can even&nbsp;identify a landmark, by just scanning through its picture. In a way it might just sound a little scary, but this image recognition technique is equally powerful and useful. Imagine how&nbsp;useful it could be in&nbsp;adding caption on your vacation images&nbsp;automatically.</p>



<div class="wp-block-image wp-image-1515 size-full"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="805" data-attachment-id="1515" data-permalink="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/android-image-recognition/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition.png?fit=500%2C805&amp;ssl=1" data-orig-size="500,805" data-comments-opened="1" data-image-title="Android Image Recognition" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition.png?fit=500%2C805&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition.png?resize=500%2C805" alt="Android Image Recognition" class="wp-image-1515" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition.png?w=500&amp;ssl=1 500w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition.png?resize=186%2C300&amp;ssl=1 186w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition.png?resize=300%2C483&amp;ssl=1 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /><figcaption>Landmark: Duquesne Incline</figcaption></figure></div>



<h3 class="wp-block-heading">4.&nbsp;LOGO_DETECTION</h3>



<p class="wp-block-paragraph">By using the new Cloud Vision API you can also&nbsp;identify some of the popular logos. Although when I&nbsp;tried this API with some logos, it&nbsp;wasn&#8217;t able to identify most of them. But, maybe in future this will get improved.</p>



<h3 class="wp-block-heading">5.&nbsp;FACE_DETECTION</h3>



<p class="wp-block-paragraph">This is also one the very powerful features of the Google Cloud Vision API. This allows us to mark the number of faces in a&nbsp;picture. It also helps in identifying the placement of individual facial features in an image. By using this image recognition technique on Android we can highlight&nbsp;a face with a polygon very easily.</p>



<h3 class="wp-block-heading">6. SAFE_SEARCH_DETECTION</h3>



<p class="wp-block-paragraph">This technique allows us to detect inappropriate images. This could majorly help in moderation of images when performing a server to server integration. Currently it supports four types of annotations <em>adult</em>, <em>spoof</em>, <em>medical</em> and <em>violence</em>.</p>



<h3 class="wp-block-heading">7.&nbsp;IMAGE_PROPERTIES</h3>



<p class="wp-block-paragraph">Android Cloud Vision API also provides a way to identify the dominant colors in an image. In a way this feature would not be very much used on Android as a great alternative in form of <a href="http://www.truiton.com/2015/05/android-palette-pick-colors-images/" target="_blank" rel="noopener noreferrer">Palette library</a> is already available, through which dominant colors can be identified.</p>



<div class="wp-block-image size-full wp-image-1517"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="805" data-attachment-id="1517" data-permalink="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/android-image-recognition-2/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition-2.png?fit=500%2C805&amp;ssl=1" data-orig-size="500,805" data-comments-opened="1" data-image-title="Android Image Recognition &amp;#8211; 2" data-image-description="" data-image-caption="&lt;p&gt;A random picture of a hotel room.&lt;/p&gt;
" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition-2.png?fit=500%2C805&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition-2.png?resize=500%2C805" alt="Android Image Recognition - 2" class="wp-image-1517" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition-2.png?w=500&amp;ssl=1 500w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition-2.png?resize=186%2C300&amp;ssl=1 186w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2016/06/Android-Image-Recognition-2.png?resize=300%2C483&amp;ssl=1 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /><figcaption>A random picture of a hotel room.</figcaption></figure></div>



<h2 class="wp-block-heading">Is Google Cloud Vision API&nbsp;Free ?</h2>



<p class="wp-block-paragraph">The answer is NO. To perform image recognition on android via this API, I assume an infrastructure cost is involved. Therefore just like most of the Google products, Cloud Vision API is FREE for initial use on all platforms but when usage increases, they will start charging you. Please find the detailed <a href="https://cloud.google.com/vision/docs/pricing">pricing plan here</a>.</p>



<h2 class="wp-block-heading">Android Image Recognition using Google&#8217;s Cloud Vision API</h2>



<p class="wp-block-paragraph">Behind the scenes Google is harnessing the power of&nbsp;<a href="http://www.tensorflow.org/" target="_blank" rel="noopener noreferrer">TensorFlow</a>&nbsp;and Machine Learning platforms to perform this powerful image analysis on Android. As I mentioned earlier through this Android image recognition technique, we can categorize our images in to thousands of tags. This will definitely help us in organizing our data in a better way; leading us to&nbsp;build better location aware apps. To build an Android image recognition app using the Cloud Vision API, hope you have enabled the API from the Cloud Console using the steps mentioned in the first section of this tutorial&nbsp;and included all the dependencies in your <code>build.gradle</code> file. Next lets move on to defining a layout where all the results would be displayed. (Although full source code is available at the end of the tutorial.)</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.truiton.cloudvisionapi.MainActivity">

    &lt;TextView
        android:id="@+id/selected_image_txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="10dp"
        android:text="Selected Image: "/>

    &lt;ImageView
        android:id="@+id/selected_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/selected_image_txt"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"/>

    &lt;TextView
        android:id="@+id/result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/selected_image"
        android:layout_marginTop="10dp"/>

    &lt;Button
        android:id="@+id/select_image_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Select Image"/>
&lt;/RelativeLayout>
</pre>



<p class="wp-block-paragraph">Next lets define the&nbsp;<code>GET_ACCOUNTS</code> and <code>INTERNET</code> permission in the manifest. As to perform an OAuth request with Android to Could Vision API we need to access the account information on the android device.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;manifest package="com.truiton.cloudvisionapi"
          xmlns:android="http://schemas.android.com/apk/res/android">

    &lt;uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    &lt;uses-permission android:name="android.permission.INTERNET"/>

    &lt;application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        &lt;activity android:name=".MainActivity">
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN"/>

                &lt;category android:name="android.intent.category.LAUNCHER"/>
            &lt;/intent-filter>
        &lt;/activity>
    &lt;/application>

&lt;/manifest></pre>



<p class="wp-block-paragraph">In&nbsp;this example to make a Google Cloud Vision API request on Android,&nbsp;we will be using Google API Client library for java. And as you might know, to perform a Google API Client OAuth request on Android we first need to get an auth token from google via a client call. Therefore lets first define a class to get an OAuth token.</p>



<p class="wp-block-paragraph"><em><strong>Please Note:</strong> Don&#8217;t forget to generate a ClientID for your OAuth token in the&nbsp;Cloud Console, using the steps mentioned in first section.</em></p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.cloudvisionapi;

import android.accounts.Account;
import android.app.Activity;
import android.os.AsyncTask;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;

import java.io.IOException;

/**
 * Created by MG on 04-06-2016.
 */
public class GetTokenTask extends AsyncTask&lt;Void, Void, Void&gt; {
    Activity mActivity;
    String mScope;
    Account mAccount;
    int mRequestCode;

    GetTokenTask(Activity activity, Account account, String scope, int requestCode) {
        this.mActivity = activity;
        this.mScope = scope;
        this.mAccount = account;
        this.mRequestCode = requestCode;
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            String token = fetchToken();
            if (token != null) {
                ((MainActivity)mActivity).onTokenReceived(token);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Gets an authentication token from Google and handles any
     * GoogleAuthException that may occur.
     */
    protected String fetchToken() throws IOException {
        String accessToken;
        try {
            accessToken = GoogleAuthUtil.getToken(mActivity, mAccount, mScope);
            GoogleAuthUtil.clearToken (mActivity, accessToken); // used to remove stale tokens.
            accessToken = GoogleAuthUtil.getToken(mActivity, mAccount, mScope);
            return accessToken;
        } catch (UserRecoverableAuthException userRecoverableException) {
            mActivity.startActivityForResult(userRecoverableException.getIntent(), mRequestCode);
        } catch (GoogleAuthException fatalException) {
            fatalException.printStackTrace();
        }
        return null;
    }
}
</pre>



<p class="wp-block-paragraph">Moving on lets define the MainActivity where the Android image recognition would take place. In this example we would perform&nbsp;<code>LABEL_DETECTION</code>,&nbsp;<code>TEXT_DETECTION</code>, and&nbsp;<code>LANDMARK_DETECTION</code>. Although if you wish to perform more analysis on single image. You can add more feature requests on the same image upload. But since this Google Could Vision API is in very nascent stage, therefore as and when more features are added, it gets slower.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.cloudvisionapi;

import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.common.AccountPicker;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.vision.v1.Vision;
import com.google.api.services.vision.v1.model.AnnotateImageRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse;
import com.google.api.services.vision.v1.model.EntityAnnotation;
import com.google.api.services.vision.v1.model.Feature;
import com.google.api.services.vision.v1.model.Image;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    private static String accessToken;
    static final int REQUEST_GALLERY_IMAGE = 10;
    static final int REQUEST_CODE_PICK_ACCOUNT = 11;
    static final int REQUEST_ACCOUNT_AUTHORIZATION = 12;
    static final int REQUEST_PERMISSIONS = 13;
    private final String LOG_TAG = "MainActivity";
    private ImageView selectedImage;
    private TextView resultTextView;
    Account mAccount;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button selectImageButton = (Button) findViewById(R.id
                .select_image_button);
        selectedImage = (ImageView) findViewById(R.id.selected_image);
        resultTextView = (TextView) findViewById(R.id.result);

        selectImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.GET_ACCOUNTS},
                        REQUEST_PERMISSIONS);
            }
        });
    }

    private void launchImagePicker() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select an image"),
                REQUEST_GALLERY_IMAGE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_PERMISSIONS:
                if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    getAuthToken();
                } else {
                    Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
                }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_GALLERY_IMAGE &amp;&amp; resultCode == RESULT_OK &amp;&amp; data != null) {
            uploadImage(data.getData());
        } else if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
            if (resultCode == RESULT_OK) {
                String email = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                AccountManager am = AccountManager.get(this);
                Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
                for (Account account : accounts) {
                    if (account.name.equals(email)) {
                        mAccount = account;
                        break;
                    }
                }
                getAuthToken();
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "No Account Selected", Toast.LENGTH_SHORT)
                        .show();
            }
        } else if (requestCode == REQUEST_ACCOUNT_AUTHORIZATION) {
            if (resultCode == RESULT_OK) {
                Bundle extra = data.getExtras();
                onTokenReceived(extra.getString("authtoken"));
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "Authorization Failed", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    public void uploadImage(Uri uri) {
        if (uri != null) {
            try {
                Bitmap bitmap = resizeBitmap(
                                MediaStore.Images.Media.getBitmap(getContentResolver(), uri));
                callCloudVision(bitmap);
                selectedImage.setImageBitmap(bitmap);
            } catch (IOException e) {
                Log.e(LOG_TAG, e.getMessage());
            }
        } else {
            Log.e(LOG_TAG, "Null image was returned.");
        }
    }

    private void callCloudVision(final Bitmap bitmap) throws IOException {
        resultTextView.setText("Retrieving results from cloud");

        new AsyncTask&lt;Object, Void, String&gt;() {
            @Override
            protected String doInBackground(Object... params) {
                try {
                    GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
                    HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
                    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();

                    Vision.Builder builder = new Vision.Builder
                            (httpTransport, jsonFactory, credential);
                    Vision vision = builder.build();

                    List&lt;Feature&gt; featureList = new ArrayList&lt;&gt;();
                    Feature labelDetection = new Feature();
                    labelDetection.setType("LABEL_DETECTION");
                    labelDetection.setMaxResults(10);
                    featureList.add(labelDetection);

                    Feature textDetection = new Feature();
                    textDetection.setType("TEXT_DETECTION");
                    textDetection.setMaxResults(10);
                    featureList.add(textDetection);

                    Feature landmarkDetection = new Feature();
                    landmarkDetection.setType("LANDMARK_DETECTION");
                    landmarkDetection.setMaxResults(10);
                    featureList.add(landmarkDetection);

                    List&lt;AnnotateImageRequest&gt; imageList = new ArrayList&lt;&gt;();
                    AnnotateImageRequest annotateImageRequest = new AnnotateImageRequest();
                    Image base64EncodedImage = getBase64EncodedJpeg(bitmap);
                    annotateImageRequest.setImage(base64EncodedImage);
                    annotateImageRequest.setFeatures(featureList);
                    imageList.add(annotateImageRequest);

                    BatchAnnotateImagesRequest batchAnnotateImagesRequest =
                            new BatchAnnotateImagesRequest();
                    batchAnnotateImagesRequest.setRequests(imageList);

                    Vision.Images.Annotate annotateRequest =
                            vision.images().annotate(batchAnnotateImagesRequest);
                    // Due to a bug: requests to Vision API containing large images fail when GZipped.
                    annotateRequest.setDisableGZipContent(true);
                    Log.d(LOG_TAG, "sending request");

                    BatchAnnotateImagesResponse response = annotateRequest.execute();
                    return convertResponseToString(response);

                } catch (GoogleJsonResponseException e) {
                    Log.e(LOG_TAG, "Request failed: " + e.getContent());
                } catch (IOException e) {
                    Log.d(LOG_TAG, "Request failed: " + e.getMessage());
                }
                return "Cloud Vision API request failed.";
            }

            protected void onPostExecute(String result) {
                resultTextView.setText(result);
            }
        }.execute();
    }

    private String convertResponseToString(BatchAnnotateImagesResponse response) {
        StringBuilder message = new StringBuilder("Results:\n\n");
        message.append("Labels:\n");
        List&lt;EntityAnnotation&gt; labels = response.getResponses().get(0).getLabelAnnotations();
        if (labels != null) {
            for (EntityAnnotation label : labels) {
                message.append(String.format(Locale.getDefault(), "%.3f: %s",
                        label.getScore(), label.getDescription()));
                message.append("\n");
            }
        } else {
            message.append("nothing\n");
        }

        message.append("Texts:\n");
        List&lt;EntityAnnotation&gt; texts = response.getResponses().get(0)
                .getTextAnnotations();
        if (texts != null) {
            for (EntityAnnotation text : texts) {
                message.append(String.format(Locale.getDefault(), "%s: %s",
                        text.getLocale(), text.getDescription()));
                message.append("\n");
            }
        } else {
            message.append("nothing\n");
        }

        message.append("Landmarks:\n");
        List&lt;EntityAnnotation&gt; landmarks = response.getResponses().get(0)
                .getLandmarkAnnotations();
        if (landmarks != null) {
            for (EntityAnnotation landmark : landmarks) {
                message.append(String.format(Locale.getDefault(), "%.3f: %s",
                        landmark.getScore(), landmark.getDescription()));
                message.append("\n");
            }
        } else {
            message.append("nothing\n");
        }

        return message.toString();
    }

    public Bitmap resizeBitmap(Bitmap bitmap) {

        int maxDimension = 1024;
        int originalWidth = bitmap.getWidth();
        int originalHeight = bitmap.getHeight();
        int resizedWidth = maxDimension;
        int resizedHeight = maxDimension;

        if (originalHeight &gt; originalWidth) {
            resizedHeight = maxDimension;
            resizedWidth = (int) (resizedHeight * (float) originalWidth / (float) originalHeight);
        } else if (originalWidth &gt; originalHeight) {
            resizedWidth = maxDimension;
            resizedHeight = (int) (resizedWidth * (float) originalHeight / (float) originalWidth);
        } else if (originalHeight == originalWidth) {
            resizedHeight = maxDimension;
            resizedWidth = maxDimension;
        }
        return Bitmap.createScaledBitmap(bitmap, resizedWidth, resizedHeight, false);
    }

    public Image getBase64EncodedJpeg(Bitmap bitmap) {
        Image image = new Image();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream);
        byte[] imageBytes = byteArrayOutputStream.toByteArray();
        image.encodeContent(imageBytes);
        return image;
    }

    private void pickUserAccount() {
        String[] accountTypes = new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE};
        Intent intent = AccountPicker.newChooseAccountIntent(null, null,
                accountTypes, false, null, null, null, null);
        startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
    }

    private void getAuthToken() {
        String SCOPE = "oauth2:https://www.googleapis.com/auth/cloud-platform";
        if (mAccount == null) {
            pickUserAccount();
        } else {
            new GetTokenTask(MainActivity.this, mAccount, SCOPE, REQUEST_ACCOUNT_AUTHORIZATION)
                    .execute();
        }
    }

    public void onTokenReceived(String token){
        accessToken = token;
        launchImagePicker();
    }
}
</pre>



<p class="wp-block-paragraph">To perform a successful Android image recognition, using the new Google Cloud Vision API, we first need to authenticate the our app and generate an OAuth token for making&nbsp;an API call. But before generating an OAuth token we may first need to pick an account through which the OAuth token can be generated. But to pick an account we first need to get a permission called&nbsp;<code>GET_ACCOUNTS</code>. Once we have the permission to get accounts, we can call the method&nbsp;<code>getAuthToken()</code> mentioned above to pick an account and get its OAuth token. This method internally takes consent from the user, using the <code>GetTokenTask</code>; after they select an&nbsp;account using the&nbsp;<code>pickUserAccount()</code> method. Now once we have this API token we can call the <code>launchImagePicker()</code> method to pick an image from gallery and pass it on to the <code>callCloudVision()</code> method which uploads the image&nbsp;to Google Cloud Vision API and applies all the Android image analysis techniques on it. This method&nbsp;internally encodes the bitmap into a jpeg, creates and sends a request to&nbsp;the google cloud vision API. Further we parse the result and display it on screen. View the full source code here:</p>



<p class="wp-block-paragraph" style="text-align:center">&nbsp;<a class="fasc-button fasc-size-large fasc-type-flat fasc-rounded-medium ico-fa fasc-ico-before fa-github" style="background-color: #0364af; color: #ffffff;" href="https://github.com/Truiton/CloudVisionAPI" target="_blank" rel="noopener noreferrer">Full Source Code</a></p>



<p class="wp-block-paragraph">In the above <a href="http://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/">Android image recognition example</a>, we simply picked an account authenticated it, selected and uploaded an image to perform image analysis on it. Although we applied&nbsp;very basic set of image recognition techniques, like&nbsp;<code>LABEL_DETECTION</code>,&nbsp;<code>TEXT_DETECTION</code>, and&nbsp;<code>LANDMARK_DETECTION</code>. Which&nbsp;gave deep insights on how google looks at an image. Maybe in future Google would enhance this API and launch something like this for videos as well. But as of now even the simple Google Cloud Vision API for images is doing wonders. Let me know what you guys are planning to build with these awesome set of APIs. Connect with us on Facebook, Google+ and Twitter for more updates.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/">Image Recognition on Andorid with Google Cloud Vision API</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2016/06/android-image-recognition-google-cloud-vision-api/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1508</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Minified using Disk

Served from: www.truiton.com @ 2026-07-02 21:43:52 by W3 Total Cache
-->