OCR with Xamarin.Form + Azure Cognitive Service - xamarin.forms

I am developing on Windows 10 with Visual Studo 2019.
I'm trying to do OCR with Xamarin.Form+Azure Cognitive Service.
I was able to set up Azure.
The project is being tested on Android (actual device 9.0) with Xamarin.
Form. After taking a picture, I use its Path.
public ReadImage()
{
var file="/mnt/sdcard/DCIM/Camera/IMG_20210122_1709.jpg";
var visionClient = Authenticate(SubscriptionKey, EndPoint);
var ocrResult1 = visionClient.RecognizePrintedTextAsync(true, "file:/" + file);
var ocrResult2 = visionClient.RecognizePrintedTextAsync(true, "file:" + file);
var ocrResult3 = visionClient.RecognizePrintedTextAsync(true, "file://" + file);
var ocrResult4 = visionClient.RecognizePrintedTextAsync(true, "file:///" + file);
}
The ocr.Result is returned with Status=Faulted.
The error message is as follows
One or more errors occurred. (Invalid URI: The format of the URI could not be determined.)
file://mnt/sdcard/DCIM/Camera/IMG_20210122_1709.jpg
file:/mnt/sdcard/DCIM/Camera/IMG_20210122_1709.jpg
file:///mnt/sdcard/DCIM/Camera/IMG_20210122_1709.jpg
file:////mnt/sdcard/DCIM/Camera/IMG_20210122_1709.jpg
What should I do with the path to Recognize in OCR?
NuGet solutions
I used RecognizePrintedTextInStreamAsync.
But Error.
var ocrResult5 = visionClient.RecognizePrintedTextInStreamAsync(true, new FileStream(file, FileMode.Open, FileAccess.Read));
//One or more errors occurred. (Invalid URI: The format of the URI could not be determined.)
var ocrResult6 = visionClient.RecognizePrintedTextInStreamAsync(true, new FileStream("file:"+file, FileMode.Open, FileAccess.Read));
//Could not find a part of the path "/file:/mnt/sdcard/DCIM/Camera/IMG_20210126_1050.jpg".
var ocrResult7 = visionClient.RecognizePrintedTextInStreamAsync(true, new FileStream(file.TrimStart('/'), FileMode.Open, FileAccess.Read));
//One or more errors occurred. (Invalid URI: The format of the URI could not be determined.)
var ocrResult8 = visionClient.RecognizePrintedTextInStreamAsync(true, new FileStream("file:/"+file, FileMode.Open, FileAccess.Read));
//Could not find a part of the path "/file:/mnt/sdcard/DCIM/Camera/IMG_20210126_105535.jpg".
var ocrResult9 = visionClient.RecognizePrintedTextInStreamAsync(true, new FileStream("file://"+file, FileMode.Open, FileAccess.Read));
//Could not find a part of the path "/file:/mnt/sdcard/DCIM/Camera/IMG_20210126_105535.jpg".
Add var stream = new FileStream(file, FileMode.Open, FileAccess.Read); result Debug image.
StearmReader is success

Related

Spire.xls - return a File from a stream for client download

Here is what I'm trying to accomplish.
I am creating an asp.net MVC application. My restrictions are that I cannot programmatically save anything to the file structure of the server, so I can't save it as a physical file on the host, and then grab it for client download.
I am loading a PDF to a stream, extracting information from the PDF, dynamically building an excel file, and then offering the file for download to the client. My code is below.
// Loads the incoming PDF document to stream
PdfDocument doc = new PdfDocument();
using (var stream = model.BudgetPdfFile.OpenReadStream())
{
doc.LoadFromStream(stream);
}
var pageCount = doc.Pages.Count;
var date = DateTime.Now.ToShortDateString().Replace("/", "-");
// Extracts data from the PDF and separates it by NewLine
SimpleTextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
StringBuilder allText = new StringBuilder();
for (var i = 0; i < pageCount; i++)
{
allText.Append(doc.Pages[i].ExtractText(strategy));
}
var fullDocText = allText.ToString();
List<string> linesList = new List<string>(fullDocText.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList());
// generates a comparison list for output data manipulation from static data
var finalList = linesList.BuildFinalList(budgetItems);
// creates a new Spire.PDF.Workbook for the final output excel file
var result = new Workbook();
// checks for whether the submitted budget is for a case in litigation or not and builds the correct excel workbook
if (model.isTrial)
{
result = ExportExcelBudget.TrialBudgetSheet(model, finalList);
}
else
{
result = ExportExcelBudget.PreTrialBudgetSheet(model, finalList);
}
Absolutely everything up to the last section below works perfectly. However, I cannot figure out how to load the workbook into a new stream and then return the file for download.
// saves the final workbook to a stream and offers it for download to the client
Stream outStream = new MemoryStream();
var fileName = "Budget Report_" + model.ClaimNumber + "_" + date + ".xlsx";
var contentType = "application/vnd.ms-excel";
result.SaveToStream(outStream, Spire.Xls.FileFormat.Version2016);
return File(outStream, contentType, fileName);
I've searched and tried multiple different variations but when the application hits the return File(), it returns a null.
I've stepped through execution and the results seem to be there, but it's not passing anything. Any help on what is wrong here would be greatly appreciated.
Stream outStream = new MemoryStream();
var fileName = "Budget Report_" + model.ClaimNumber + "_" + date + ".xlsx";
var contentType = "application/vnd.ms-excel";
result.SaveToStream(outStream, Spire.Xls.FileFormat.Version2016);
**outStream.Position = 0;**
return File(outStream, contentType, fileName);
Had to reset the stream position to 0. Working perfectly now.

Xamarin Forms: Get the path of an image file stored on the shared project?

I am trying to upload an image file as ByteArrayContent through my web service. I have added all the images to the shared project and set the build action as Embedded resource.
Following is my code:
var fileBytes = File.ReadAllBytes("Avatars." + selectedAvatar);
var byteContent = new ByteArrayContent(fileBytes);
content.Add(byteContent, "file", selectedAvatar);
When I try like above I am getting System.IO.FileNotFoundException: Could not find file "/Projectname.Avatars.ic_avatar01_xx.png"
Added the images directly inside a folder in the shared project like the below screenshot.
:
I tried changing the . with a / in the file path, like below:
var fileBytes = File.ReadAllBytes("Avatars/" + selectedAvatar);
var byteContent = new ByteArrayContent(fileBytes);
content.Add(byteContent, "file", selectedAvatar);
But in that case, I am getting the System.IO.DirectoryNotFoundException: Could not find a part of the path "/Avatars/ic_avatar01_xx.png"
What is the correct way to get the path of an image file stored on a shared project?
Also tried another approach:
string avatarFileName = "Avatars/" + selectedAvatar;
var assembly = typeof(ProfilePage).GetTypeInfo().Assembly;
var stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{avatarFileName}");
content.Add(stream, "file", avatarFileName);
But in the above case I am getting the below error:
If you want to upload the image with Stream , you could check the following code
private async Task<string> UploadImage(Stream FileStream)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://your.url.com/");
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
form.Add(content, "fileToUpload");
content = new StreamContent(FileStream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = "xxx.png"
};
form.Add(content);
var response = await client.PostAsync("http://your.url.com/", form);
return response.Content.ReadAsStringAsync().Result;
}
Option 2:
You could also use the plugin FileUploaderPlugin . It support uploading multiple files at once
Uploading from a file path
CrossFileUploader.Current.UploadFileAsync("<URL HERE>", new FilePathItem("<REQUEST FIELD NAME HERE>","<FILE PATH HERE>"), new Dictionary<string, string>()
{
{"<HEADER KEY HERE>" , "<HEADER VALUE HERE>"}
}
);
Option 3:
The first parameter of MultipartFormDataContent is HttpContent. To handle the stream, try using the StreamContent type which inherits from the HttpContent. Get the streamContent from the stream and add id to the MultipartFormDataContent.
string avatarFileName = "Avatars." + selectedAvatar;
var assembly = typeof(ProfilePage).GetTypeInfo().Assembly;
var stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{avatarFileName}");
var streamContent = new StreamContent(stream);
content.Add(streamContent, "file", avatarFileName);

File Uploading using HttpClient in .Net core 3.0 Console Application

I am trying to upload file using HttpClient in Asp.net Core 3, but It is not uploading file to the server. If I try to upload file to the server via Postman, it works.
Below is my simple code to upload file:
HttpClient _client = new HttpClient();
var stream = new FileStream("main.txt", FileMode.Open);
byte[] fileBytes = new byte[stream.Length];
stream.Write(fileBytes, 0, (int)stream.Length);
stream.Dispose();
using (var content = new MultipartFormDataContent())
{
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Test",
};
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
content.Add(fileContent);
_client.PostAsync("http://192.168.56.1:8000", content);
}
As I said above it is working with Postman. I am putting a screenshot which shows that how I doing with Postman.
when I debug the code, so I get below error.
One solution is that you could use MemoryStream to transform the content of the file. Your method will cause the content in the main.txt file to become empty.
Change your code like this:
HttpClient _client = new HttpClient();
Stream stream = new FileStream("main.txt", FileMode.Open);​
MemoryStream ms = new MemoryStream();​
stream.CopyTo(ms);​
byte[] fileBytes = ms.ToArray();​
ms.Dispose(); ​
Another way is that use System.IO.File.ReadAllBytes(filePath).
Try to post file using below example code instead, refer to my answer.
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
//replace with your own file path, below use an txt in wwwroot for example
string filePath = Path.Combine(_hostingEnvironment.WebRootPath, "main.txt");
byte[] file = System.IO.File.ReadAllBytes(filePath);
var byteArrayContent = new ByteArrayContent(file);
content.Add(byteArrayContent, "file", "main.txt");
var url = "https://localhost:5001/foo/bar";
var result = await client.PostAsync(url, content);
}
}
foo/bar action
[HttpPost]
[Route("foo/bar")]
public IActionResult ProcessData([FromForm]IFormFile file)
{
//your logic to upload file
}
I've downloaded the server and tested it with this code. The server returns 200 OK
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
using (var fileStream = new FileStream("test.txt", FileMode.Open))
{
var fileContent = new StreamContent(fileStream);
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
content.Add(fileContent, "file", "test.txt");
var response = await client.PostAsync("http://192.168.56.1:8000/", content);
}
}
}

Unable to access QRCode OR QRCodeGenerator.QRCode class while using QRCoder library version 1.3.5

I am unable to access QRCode class OR QRCodeGenerator.QRCode, while I am using QRCode.dll version 1.3.5 or I have checked version 1.3.3 but getting same issue.
public void GenerateQRCode(string code)
{
var imgUrl="";
//string code = txtCode.Text;
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(code, QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
// I am getting error in above line, or I am using below line of code but getting error. Unable to access QRCode withQRCodeGenerator.
QRCodeGenerator.QRCode qrCode = qrGenerator.CreateQrCode(code, QRCodeGenerator.ECCLevel.Q);
using (Bitmap bitMap = qrCode.GetGraphic(20))
{
using (MemoryStream ms = new MemoryStream())
{
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
imgUrl= "data:image/png;base64," + Convert.ToBase64String(byteImage);
}
}
}
Above is the code which I am using in web API 2

Streaming a blob from Azure storage - Cannot access a closed Stream

I am using asp.net webforms.
I have pdfs in Azure storage that I need to process. I am using PDFJet library in order to do that.
I would like to
stream the pdf without downloading it as I have to process a large number of pdfs.
I am using the following function to stream the pdfs from Azure:
public MemoryStream DownloadToMemoryStream(DTO.BlobUpload b)
{
CloudStorageAccount storageAccount = Conn.SNString(b.OrgID);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(b.Container);
CloudBlockBlob blob = container.GetBlockBlobReference(b.FileName);
var sasToken = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10),//assuming the blob can be downloaded in 10 miinutes
}, new SharedAccessBlobHeaders()
{
ContentDisposition = "attachment; filename=file-name"
});
using (MemoryStream ms = new MemoryStream())
{
blob.DownloadToStream(ms);
return ms;
}
}
And in the aspx.cs page the following code to read the pdf stream:
BufferedStream pdfScript = new BufferedStream(new FileStream(ScriptPath + Script, FileMode.Open));
SortedDictionary<Int32, PDFobj> objects = pdfFinalScript.Read(pdfScript);
However I get the error message: Cannot access a closed Stream
If I download the pdf to disk, this is the function I use, this work but it is not practical:
blockBlob.DownloadToFile(b.LocalPath + b.FileName, FileMode.Create);
BufferedStream pdfScript = new BufferedStream(new FileStream(ScriptPath + Script, FileMode.Open));
Thank you for your help.
Cannot access a closed Stream
According to error information, it indicates that you need to reset stream position.
Please have a try to reset the stream position before return it.
blob.DownloadToStream(ms);
ms.Position = 0; //add this code
return ms;
Updated:
ms was closed if out of using section. So please have a try to use the following code.
MemoryStream stream = new MemoryStream();
using (MemoryStream ms = new MemoryStream())
{
blob.DownloadToStream(ms);
ms.Position = 0
ms.CopyTo(stream);
stream.Position = 0;
return stream;
}

Resources