Google cloud vision - product search return null for base64 image - base64

I'm implementing google cloud vision for the first time.
Successfully created product set, products and assigned images to products.
When I try to execute product search sending base64 encoded image the result is always null. But when I try it with image from google cloud storage it's working. Any idea why it's not working?
$productSearchClient = new ProductSearchClient();
$productSetPath = $productSearchClient->productSetName(config('web.google_vision.project_id'), config('web.google_vision.location'), 2);
# product search specific parameters
$productSearchParams = (new ProductSearchParams())
->setProductSet($productSetPath)
->setProductCategories(['general-v1']);
# search products similar to the image
$imageAnnotatorClient = new ImageAnnotatorClient();
//$image = 'gs://picfly-bucket/wendys-5.jpeg';
$image = base64_encode(file_get_contents(public_path('gallery/test/wendy-search.png')));
$response = $imageAnnotatorClient->productSearch($image, $productSearchParams);
dd($response->getProductSearchResults());

As per this doc, your code reads a local file and queries the API by including inline the raw image bytes (base64 encoded image) in the request. So, you should not call base64_encode() explicitly. The Vision library does the base64 encoding by default. You just need to call fopen() to open your local image data. The code would look like:
$image = fopen('gallery/test/wendy-search.png', 'r');
$response = $imageAnnotatorClient->productSearch($image, $productSearchParams);

Related

Extract data from PDFs at scale with form recognizer: HttpResponseError: (FailedToDownloadImage) Failed to download image from input URL on Databricks

I am trying to extract data from pdfs at scale with Azure Form Recognizer. I am using the code example at github
I have entered the code as follows:
import pandas as pd
field_list = ["InvoiceId", "VendorName", "VendorAddress", "CustomerName", "CustomerAddress", "CustomerAddressRecipient", "InvoiceDate", "InvoiceTotal", "DueDate"]
df = pd.DataFrame(columns=field_list)
for blob in container.list_blobs():
blob_url = container_url + "/" + blob.name
poller = form_recognizer_client.begin_recognize_invoices_from_url(invoice_url=blob_url)
invoices = poller.result()
print("Scanning " + blob.name + "...")
for idx, invoice in enumerate(invoices):
single_df = pd.DataFrame(columns=field_list)
for field in field_list:
entry = invoice.fields.get(field)
if entry:
single_df[field] = [entry.value]
single_df['FileName'] = blob.name
df = df.append(single_df)
df = df.reset_index(drop=True)
df
However, I keep on getting the following error:
HttpResponseError: (FailedToDownloadImage) Failed to download image from input URL.
My URL looks like the following:
https://blobpretbiukblbdev.blob.core.windows.net/demo?sp=racwdl&st=2022-05-21T19:39:07Z&se=2022-05-22T03:39:07Z&sv=2020-08-04&sr=c&sig=XYhdecG2jKF8aNPPpkcP%2FCGVVRKYTFPrOQYdNDsASCA%3D/pdf1.pdf
NB:
The key has been regenerated, I have just left the key in as it will appear in my code for illustration.
Where might I be going wrong?
As mentioned in REST API supportive documentation, there is a need to specify the Content-Type. There is a need to set the public access to source via JSON file. Set the Content-Type to application/pdf. To make this work, there is a need to install filetype package using link
pip install filetype
Check this link for better implementation of REST API to user Form Recognizer SDK.

can't access parameters in body after file upload

I am trying to write an API, which takes a .csv file and upload it to s. (I am using node.js lambda)
When I upload the CSV file to Postman in form-data and checked the log of body, I got a JSON like this, I can't access the filename or mime type, in (body. file-name/ body.mime/body.file), I need to access these contents,
body:"----------------------------262926577667427333659506\r\nContent-Disposition: form-data; name=\"file\"; filename=\"User_Invoice_Details.csv\"\r\nContent-Type: text/csv\r\n\r\nUser Invoice Details,,,,,,,,,,,,,,,,,,,\r\n,,,,,,,,,,,,,,,,,,,\r\nInvoicenumber,Billingaccountnumber,Username,Invoicedate,Expirydate,Lcoid,Lconame,Customername,Address,Packagename,Cycle,Invoiceamount,Cgst,Sgst,Igst,Totalamount,Statecode,Gstinnumber,Revenueshare,Technology\r\n1734145,INDI0002832755,Treatmentcottage,23-06-2021 12:00,23-07-2021 11:59,LCO002776,S.N.T Network(Patna),Anand Kumar,Mithapur B Area Jakkanpur Behind Bhanamal Work Shop Nahar Par,INDI_UL50,1,483,0,0,0,483,10,,40,EOC\r\nBH2122/06/000001,INDI0001657582,TESA,01-06-2021 12:00,01-07-2021 11:59,LCO002712,Satellite Entertainment(MaripurMuzaffarpur),G.m. Cum Chief Engineer,G.m. Cum CeBhagwanpur Chatti,INDI_UL50,1,483,43.47,0,43.47,569.94,10,,50,Ethernet\r\nBH2122/06/000002,INDI0002300704,vikashkumar#rs,01-06-2021 12:00,01-07-2021 11:59,LCO002775,RS Cable Tv Network(Patna),Vikash Kumar,\"Barah Patthar Ward No 15, Gali No 2,\",INDI_UL50,1,483,43.47,0,43.47,569.94,10,,45,Ethernet\r\nBH2122/06/000003,INDI0002024824,sunny_kumar,01-06-2021 12:00,01-07-2021 11:59,LCO002645,New S K cable(Patna),Sunny Kumar,Neem Gali Sekhpura Patna,INDI_UL50,1,483,43.47,0,43.47,569.94,10,,50,Ethernet\r\nBH2122/06/000004,INDI0001673495,rajhusain_bh,01-06-2021 12:00,01-07-2021 11:59,LCO003066,FLYNET COMMUNICATION (Bhore),Rajhusain Ansari,S/o Hajrat AnsariKarmaini Kateya,EXPRESS,1,483,43.47,0,43.47,569.94,10,,40,Ethernet\r\nBH2122/06/000005,INDI0001850021,yogendra_bh,01-06-2021 12:00,01-07-2021 11:59,LCO003066,FLYNET COMMUNICATION (Bhore),Yogendra Prajapati,S/o Umashankar Prajapati,EXPRESS,1,483,43.47,0,43.47,569.94,10,,40,Ethernet\r\nBH2122/06/000006,INDI0001657842,pmsingh_bh,01-06-2021 12:00,01-07-2021 11:59,LCO003066,FLYNET COMMUNICATION (Bhore),Param Manohar Singh,\"S/o. Ramswaroop Singh , Bairagi Tola, Songarhwa\",EXPRESS,1,483,43.47,0,43.47,569.94,10,,40,Ethernet\r\n,,,,,,,,,,,,,,,,,,,\r\n,,,,,,,,,,,,,,,,,,,\r\n,
You can use lambda-multipart-parser npm package to parse form-data in your lambda function It'll give you the file name and type easily.
const parser = require('lambda-multipart-parser');
const result = await parser.parse(event);
console.log(result.files)

Resize image and store into Storage in Laravel 7

So far I'm uploading an image with the following code bellow:
if($request->hasFile('image')) {
$path = $request->image->getClientOriginalName();
$name = time() . '-' . $path;
$news->image = $request->file('image')->storeAs('public/news', $name);
}
It checks for file image, revert to it original name, creating a time format attached to the image filename and uploading into storage in the desired folder.
How can I resize that image before uploading into the file directory?
I've read about the Intervention, which is included in Laravel 7 but can someone help me to achieve this using Intervention and combine with my logic of uploading an image?
I've tried like this:
use Intervention\Image\ImageManagerStatic as Image; // use Intervention
if($request->hasFile('image')) {
$path = $request->image->getClientOriginalName();
$resize = Image::make($path)->fit(300);
$name = time() . '-' . $resize;
$news->image = $request->file('image')->storeAs('public/news', $name);
}
but I'm getting Image source not readable error.
Visibly, Intervention can't read your image, check the path you give it.
dd($path);
In my case, this is how I proceed:
$img = Image::make('storage/'.$banner)->resize(800, 250);
Then to resize your image before uploading it, you can do like this:
//$image is the temporary path of your image (/tmp/something)
$image = $request->image;
//Create a Image object with the tmp path
$resized_img = Image::make($image);
//Do what you want and save your modified image on the same temporary path as the original image.
$resized_img->fit(300)->save($image);
//Upload your image on your bucket and get the final path of your image
$path = $image->storeAs('public/news', $name)
I've found a solution after a long testing. This is my code bellow:
if($request->hasFile('image')) {
$image = $request->file('image');
$imageName = $image->getClientOriginalName();
$fileName = 'public/news/' . time() . '-' . $imageName;
Image::make($image)->resize(600,300)->save(storage_path('app/' . $fileName));
$news->image = $fileName;
}
The main issue was the path and also I don't need to use storeAs() function, simply just using the Intervention functions...that's all.
This approach is lot more flexible and it's very easy to implement additional features from the wonderful Intervention library.

Google Slides API: no "client_secret.json"

I'm new to Google Slides API and am trying to build a slide deck for daily news headlines by replacing image and text placeholders (for your reference, see https://www.youtube.com/watch?v=8LSUbKZq4ZY and http://wescpy.blogspot.com/2016/11/using-google-slides-api-with-python.html).
But when I try to run my modified program, I get an error message that says no file or directory exists called "client_secret.json" (which is included in the API tutorial's code). The tutorial code is from 2 years ago so I'm not sure if there's been any updates in the Google Slides API, but I'd really appreciate help on navigating this issue. Below is my code (note: "scraped list" is a list of dictionaries, with each dictionary containing a value for keys "headline" and "imgURL".)
from __future__ import print_function
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from datetime import date
from scrapef2 import scrape
scrapedlist = scrape()
TMPLFILE = 'CrimsonTemplate' # use your own!
SCOPES = (
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/presentations',
)
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
SLIDES = discovery.build('slides', 'v1', http=HTTP)
rsp = DRIVE.files().list(q="name='%s'" % TMPLFILE).execute().get('files')[0]
DATA = {'name': '[DN] '+ str(date.today())}
print('** Copying template %r as %r' % (rsp['name'], DATA['name']))
DECK_ID = DRIVE.files().copy(body=DATA, fileId=rsp['id']).execute().get('id') # TO DO: How to copy into a specific folder
for i in range(3):
print('** Get slide objects, search for image placeholder')
slide = SLIDES.presentations().get(presentationId=DECK_ID,
fields='slides').execute().get('slides')[i]
obj = None
for obj in slide['pageElements']:
if obj['shape']['shapeType'] == 'RECTANGLE':
break
print('** Replacing placeholder text and icon')
reqs = [
{'replaceAllText': {
'containsText': {'text': '{{Headline}}'},
'replaceText': scrapedlist[i]["headline"]
}},
{'createImage': {
'url': scrapedlist[i]["imgURL"],
'elementProperties': {
'pageObjectId': slide['objectId'],
'size': obj['size'],
'transform': obj['transform'],
}
}},
{'deleteObject': {'objectId': obj['objectId']}},
]
SLIDES.presentations().batchUpdate(body={'requests': reqs},
presentationId=DECK_ID).execute()
print('DONE')
Never used python google api but error indicates that you dont have your 'client_secret.json' file or it is in wrong place.
Scenario 1 - you dont have 'client_secret.json' file
This file is used by API to automatically verify that you are you. With this all API calls are made by your behalf. To get this file:
go to Google API console
open your project (or create new one)
click "Enable APIs and services" to find and enable Google Slides API
click "Credentials" in left menu, and then "Create credentials" -> "oAuth client ID"
choose Web application, accept all windows
now you should see new credentials on list, you can click on them and there will be button on top menu named "download JSON", there you will obtain your credentials (which by name are secret so keep them somewhere safe)
Scenario 2 - your 'client_secret.json' file is in wrong place
In this case I can't be very helpful, just try to inspect library to know where it looks for file and put it there (library directory, project root directory, hard to tell).
Let me know if it worked, as Google APIs and their libraries sometimes acts unexpectedly.

Trouble in decoding the Path of the Blob file in Azure Search

I have set a Azure search for blob storage and since the path of the file is a key property it is encoded to Base 64 format.
While searching the Index, I need to decode the path and display it in the front end. But when I try to do that in few of the scenarios it throws error.
int mod4 = base64EncodedData.Length % 4;
if (mod4 > 0)
{
base64EncodedData += new string('=', 4 - mod4);
}
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.ASCII.GetString(base64EncodedBytes);
Please let me know what is the correct way to do it.
Thanks.
Refer to Base64Encode and Base64Decode mapping functions - the encoding details are documented there.
In particular, if you're using .NET, you should use HttpServerUtility.UrlTokenDecode method with UTF-8 encoding, not ASCII.

Resources