Demo cordova application reverse image search
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
Originally published at https://twiserandom.com on January 21, 2021.