This application uses google reverse image search , in order to try and guess what an image represents . It simply returns the text found in the topstuff
element , returned by google , when submitting an image , to google reverse image search .
To create this application , execute these commands :
$ cordova create what-is-this-img com.twiserandom.mobileapps.demo.whatIsThisImg "What is this img" $ cordova platform add ios $ cordova platform add android $ cordova plugin add cordova-plugin-camera $ cordova plugin add cordova-plugin-file-transfer
Edit www/index.html
to look like this :
<!DOCTYPE html> <html> <head > <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" > <meta name="format-detection" content="telephone=no"> <meta name="msapplication-tap-highlight" content="no"> <meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover"> <meta name="color-scheme" content="light dark"> <title>What is this img ?</title> </head> <body > <div id="wisThisImgApp"> </div> <script src="cordova.js"></script> <script src="js/imgSearchBtn.js"></script> <script src="js/imgSearchForm.js"></script> <script src="js/searchResult.js"></script> <script src="js/wisThisImgApp.js"></script> <script src="js/googleImageSearch.js"></script> <script src="js/index.js"></script> <script> window.addEventListener('load', wisThisImgApp ); </script> </body> </html>
Edit www/js/index.js
, to look like this :
/*File : www/js/index.js .*/ document.addEventListener('deviceready', onDeviceReady, false ); let isDeviceReady = false; function onDeviceReady( ){ isDeviceReady = true ; } function userSelectionMade( ){ function cameraSuccess(imageURI ){ switch(searchPreferences.searchProvider ){ case searchOptions.searchProvider.googleImageSearch: googleImageSearch(imageURI ); break; } } function cameraFailure(errorMsg ){ togleIsSearchPerformed( ); toggleSearch_ResultMessage(errorMsg );} if(isDeviceReady && !searchPreferences.isSearchPerformed ){ togleIsSearchPerformed( ); toggleSearch_ResultMessage( ); let pictureOptions = { } ; if(searchPreferences.imageSource == searchOptions.imageSource.Gallery ) pictureOptions = {sourceType: Camera.PictureSourceType.PHOTOLIBRARY } navigator .camera .getPicture(cameraSuccess , cameraFailure , pictureOptions ); } }
Add the following javascript files :
www/js/imgSearchBtn.js
/*File : www/js/imgSearchBtn.js .*/ function imgSearchBtn(){ let style = ` #imgSearchBtn{ background-color: white; color : black; text-align: center; font-size : 1.625rem; margin-top : 0.25rem; margin-bottom: 0.75rem; border-radius: 20% 30% 5% 5%; box-shadow: 0px 0px 0.25rem 0.25rem black; text-shadow: -0.0625rem -0.0625rem 0.125rem black ; } `; let html = ` <div id="imgSearchBtn" onclick="userSelectionMade( )" > Search </div>`; return { html : html , style : style } }
www/js/imgSearchForm.js
/*File : www/js/imgSearchForm.js*/ function imageSource(){ let style = ` #imageSource{ display: flex; flex-wrap: wrap; border-bottom: 0.0625rem solid; border-top: 0.0625rem dashed; margin-bottom: 1rem; padding: 0.375rem 0px 0.5rem; justify-content: center; } #imageSourceTitle{ padding-bottom: 0.25rem; font-family: monospace; font-size: 1.375rem; text-align: center; margin-bottom: 0.25rem; width: 100%; align-content: center; } .imageSourceName{ margin-right: 0.375rem; }`; let html =` <div id="imageSource" > <p id="imageSourceTitle"> Image Source </p> <span class="imageSourceName"> Camera </span> <input oninput="imageSourceSelected(this );" style="margin-right: 20%;" type="radio" value="${searchOptions.imageSource.Camera}" name="imageSource" checked > <span class="imageSourceName" > Gallery </span> <input oninput="imageSourceSelected(this );" type="radio" value="${searchOptions.imageSource.Gallery}" name="imageSource"> </div> `; let script = `function imageSourceSelected(inputElem ){ switch(inputElem.value ){ case searchOptions.imageSource.Gallery: searchPreferences.imageSource = searchOptions.imageSource.Gallery; break; case searchOptions.imageSource.Camera: searchPreferences.imageSource = searchOptions.imageSource.Camera; break; } }`; return{ html: html, style: style , script: script } } function searchProvider( ){ let style= ` #searchProviders{ display: flex; flex-wrap: wrap; border-bottom: 0.0625rem solid; border-top: 0.0625rem dashed; margin-bottom: 1rem; padding: 0.5rem 0px 0.5rem; justify-content: center } #searchProvidersTitle{ padding-bottom: 0.375rem; font-family: monospace; font-size: 1.375rem; text-align: center; margin-bottom: 0.5rem; width: 100%; align-content: center; } #searchProvidersOptions{ width: 100%; margin: 0px 0.625rem; color: black; } #googleImageSearch{ background-color: white; padding-top: 0.125rem; padding-left: 0.1875rem; padding-bottom: 0.25rem; box-shadow: 0px 0px 0.25rem 0.25rem white; } #bingImageSearch{ background-color: black; color: white; padding-top: 0.4375rem; padding-bottom: 0.3125rem; padding-left: 0.5rem; border: 0.0625rem solid; } #yandexImageSearch{ background-color: white; padding-top: 0.3125rem; padding-bottom: 0.3125rem; padding-left: 1rem; } #notYetImplemented{ background-color: black; color: white; border: 0.0625rem solid; padding-top: 0.4375rem; padding-bottom: 0.3125rem; padding-left: 1.625rem; }`; let html=` <div id = "searchProviders" > <p id = "searchProvidersTitle" > Search Providers </p> <div id = "searchProvidersOptions" > <p id = "googleImageSearch" data-option-value = "${searchOptions.searchProvider.googleImageSearch}" > Google Image Search ✔ </p> <p id = "bingImageSearch" data-option-value = "${searchOptions.searchProvider.bingImageSearch}" > Bing Image Search </p> <p id = "yandexImageSearch" data-option-value = "${searchOptions.searchProvider.yandexImageSearch}" > Yandex Image Search </p> <p id="notYetImplemented" data-option-value = "${searchOptions.searchProvider.notYetImplemented}" > 🕖 Not Yet Implemented </p> </div> </div>`; return{ style : style , html : html } } function searchForm( ){ let html=` <form id="imgSearchForm" onsubmit="return false;" > </form>`; return{ html : html , id: "imgSearchForm", childrens :[ imageSource() , searchProvider() ] }}
www/js/searchResult.js
/*File : www/js/searchResult.js .*/ function searchResult( ){ let componentGlobalName = 'searchResult' ; let style=` #searchResult{ text-align:center; }`; let html=` <div id = "searchResult" > </div>`; let script=` function toggleSearch_ResultMessage(result ){ result = result || "Performing search" ; this.innerText = result ; } toggleSearch_ResultMessage = toggleSearch_ResultMessage.bind(document.getElementById('${componentGlobalName}' ) );`; return{ style : style , html : html , script : script }; }
www/js/googleImageSearch.js
function googleImageSearch(imageURI ){ postImgGoogle(imageURI ); function postImgError(fileTransferError ){ toggleSearch_ResultMessage(JSON.stringify(fileTransferError , null , 4 ) ); togleIsSearchPerformed( ); } function postImgSuccess(fileUploadResult ){ let domParser = new DOMParser( ); let domDocument = domParser.parseFromString(fileUploadResult.response , 'text/html' ); let topSuggestion_Element = domDocument.getElementById("topstuff" ); toggleSearch_ResultMessage(topSuggestion_Element .textContent .trim( ) .split("\n" ) .pop( ) .trim( ) ); togleIsSearchPerformed( ); } function postImgGoogle(imageURI){ let googleImageUploadUrl = encodeURI("https://www.google.com/searchbyimage/upload" ); let options = new FileUploadOptions(); options.fileKey = "encoded_image"; options.fileName = "encoded_image"; var params = { image_url : "" , image_content : "", filename : "", hl : "en" }; options.params = params; let fileTransfer = new FileTransfer(); fileTransfer .upload( imageURI , googleImageUploadUrl , postImgSuccess, postImgError, options ); } }
Edit the file config.xml
in the root of your app , to look like this :
<?xml version='1.0' encoding='utf-8'?> <widget id="com.twiserandom.mobileapps.demo.whatIsThisImg" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <name>What is this img</name> <description> A sample Apache Cordova application that responds to the deviceready event. </description> <author email="dev@cordova.apache.org" href="http://cordova.io"> Apache Cordova Team </author> <content src="index.html" /> <access origin="*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="sms:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <platform name="android"> <allow-intent href="market:*" /> </platform> <platform name="ios"> <allow-intent href="itms:*" /> <allow-intent href="itms-apps:*" /> </platform> <!-- Android manifest permission internet --> <config-file target="AndroidManifest.xml" parent="/manifest" xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> </config-file> <!-- IOS camera access , for cordova camera plugin --> <edit-config target="NSCameraUsageDescription" file="*-Info.plist" mode="merge"> <string>need camera access to take pictures</string> </edit-config> <edit-config target="NSPhotoLibraryUsageDescription" file="*-Info.plist" mode="merge"> <string>need photo library access to get pictures from there</string> </edit-config> <edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge"> <string>need location access to find things nearby</string> </edit-config> <edit-config target="NSPhotoLibraryAddUsageDescription" file="*-Info.plist" mode="merge"> <string>need photo library access to save pictures there</string> </edit-config> <preference name="CameraUsesGeolocation" value="false" /> <!-- IOS camera access , for cordova camera plugin --> </widget>
Now you can run the application , by using :
$ cordova emulate android $ cordova emulate ios