Azure OCR RecognizePrintedTextInStreamAsync Invalid Image - xamarin

I'm trying to use the Azure OCR API in Xamarin Forms. Here is the important bits of code. I'm using the ComputerVisionClient .net client
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
SaveToAlbum = false
});
Img = new Image
{
Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
return stream;
}),
};
using (var photoStream = file.GetStream())
{
var text = await _client.RecognizePrintedTextInStreamAsync(true, photoStream);
}
The Img is bound to an image on the view and it shows up when I take a picture so there is definetly an image. However RecognizePrintedTextInStreamAsync returns back "System.IO.FileNotFoundException: 'Invalid Image'" and I'm not sure why. Any ideas?
Edit. Added _client code
public static ComputerVisionClient Authenticate(string endpoint, string key)
{
ComputerVisionClient client =
new ComputerVisionClient(new ApiKeyServiceClientCredentials(key))
{ Endpoint = endpoint };
return client;
}
Called from my constructor and set as a global var
_client = Authenticate(endpoint, subscriptionKey);
Thanks

Related

Cloud blob container uploading file working fine locally, but not working after hosting application

I don't know why getting the problem, earlier its working fine at local environment as well as at hosting environment. But now getting issue and getting the blank cloudBlockBlob.Uri.AbsoluteUri as well as image is not uploading at container.
private async Task<string> UploadToAzureAsync(IFormFile file)
{
try
{
var cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
var cloudBlobContainer = cloudBlobClient.GetContainerReference("filecontainer");
if (await cloudBlobContainer.CreateIfNotExistsAsync())
{
await cloudBlobContainer.SetPermissionsAsync(new BlobContainerPermissions()
{
PublicAccess = BlobContainerPublicAccessType.Off
});
}
var fileName = file.FileName.Split("\\").LastOrDefault().Split('/').LastOrDefault();
var cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(fileName);
cloudBlockBlob.Properties.ContentType = file.ContentType;
await cloudBlockBlob.UploadFromStreamAsync(file.OpenReadStream());
var url = cloudBlockBlob.Uri.AbsoluteUri;
return url ?? string.Empty;
}
catch (Exception)
{
return string.Empty;
}
}
Can anyone help me on this.
Thanks in advance!
You may try the below code:
[HttpPost]
public async Task UploadFileAsync([FromForm] IFormFile file)
{
CloudStorageAccount storageAccount = null;
if(CloudStorageAccount.TryParse(_configuration.GetConnectionString("StorageAccount"), out storageAccount))
{
var client = storageAccount.CreateCloudBlobClient();
var container = client.GetContainerReference("fileupload");
await container.CreateIfNotExistsAsync();
var blob = await container.GetBlobReferenceFromServerAsync(file.FileName);
await blob.UploadFromStreamAsync(file.OpenReadStream());
return Ok(blob.Uri);
}
return StatusCode(StatusCodes.Status500InternalServerError);
}

Get image stream from TakePhotoAsync()

I am getting an image stream from TakePhotoAsync Method? Where do I need to change the code?
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Alert", "No camera is available!", "OK");
return;
}
camreaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Small,
//SaveToAlbum = true,
Directory = "Sample",
Name = "test.jpg"
});
//mediaFile = await CrossMedia.Current.TakePhotoAsync();
if (camreaFile == null)
return;
fileName.Text = camreaFile.AlbumPath;
await DisplayAlert("File Location", camreaFile.Path, "OK");
image.Source = ImageSource.FromStream(() =>
{
var stream = camreaFile.GetStream();
//camreaFile.Dispose();
return stream;
});
--Pass parameter for server
if(mediaFile !=null)
{
MultipartFormDataContent content = new
MultipartFormDataContent();
content.Add(new StringContent(AppSetting.UserName),
"userId");
content.Add(new StringContent(remark), "remarks");
content.Add(new StringContent(AppSetting.ConsignmentNumebr), "consignmentNo");
content.Add(new StringContent(AppSetting.TaskId), "jobId");
content.Add(new StreamContent(cameraFile.GetStream()),"\"file\"",$"\"{AppSetting.ConsignmentNumebr + ".png"}\"");
var httpClient = new HttpClient();
var uploadServiceBaseAddress = "myserver/api/UploadContainerImage/"; var uploadResponseMessage = await httpClient.PostAsync(uploadServiceBaseAddress, content);uploadResponseMessage.Content.ReadAsStringAsync(); }
--I expect the output that successfully reaches the server.
Dispose of the Media file after you send it to the server to avoid this exception.
If you do that before you are sending it to the server, of course, it will give you an ObjectDisposedException
If you want to dispose of this variable just do it after the service call something like below:
FooServiceMethod();
mediaFile.Dispose();

How to save canvas image in .net core 2.1

I'm trying to send a javascript canvas blob image by capturing from video element to my controller method in ASP.NET Core 2.1.
I have successfully captured image and from captureimage function i am passing blob to controller, I'm using this code:
and from controller action method i don't know how to save the image.
thanks for help.
function captureimage(){
var video = document.querySelector(videoId);
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0);
//trigger the registered vall back with the blob
canvas.toBlob(
var formdata = new FormData();
formdata.append("image", blob);
return $.ajax({
type: "POST",
dataType: 'json',
url: `Info/SaveImage',
contentType: false,
processData: false,
data: formdata
}).then(function () {
});
);
public async Task<ActionResult> SaveImage(IFormFile image)
{
//how to save from IfromFile.
}
i don't know how to save the image
It depends on where you want to save the image.
For saving to server disk, you could try code like below:
[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
long size = files.Sum(f => f.Length);
// full path to file in temp location
var filePath = Path.GetTempFileName();
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
// process uploaded files
// Don't rely on or trust the FileName property without validation.
return Ok(new { count = files.Count, size, filePath});
}
For saving image byte to database, try code like below:
public async Task<IActionResult> Register(RegisterViewModel model)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser {
UserName = model.Email,
Email = model.Email
};
using (var memoryStream = new MemoryStream())
{
await model.AvatarImage.CopyToAsync(memoryStream);
user.AvatarImage = memoryStream.ToArray();
}
// additional logic omitted
// Don't rely on or trust the model.AvatarImage.FileName property
// without validation.
}

View pdf instead of download using PDF js

In my page, I'm trying to display a thumbnails of my pdf using PDF JS and it works on local, but when I upload my code in my webserver the pdf file is auto download.
In my local :
Code :
$(function() {
var filePath = "http://example.com/public/uploads/docs/Document_One_1.pdf";
function Num(num) {
var num = num;
return function () {
return num;
}
};
function renderPDF(url, canvasContainer, options) {
var options = options || {
scale: 1.1
},
func,
pdfDoc,
def = $.Deferred(),
promise = $.Deferred().resolve().promise(),
width,
height,
makeRunner = function(func, args) {
return function() {
return func.call(null, args);
};
};
function renderPage(num) {
var def = $.Deferred(),
currPageNum = new Num(num);
pdfDoc.getPage(currPageNum()).then(function(page) {
var viewport = page.getViewport(options.scale);
var canvas = document.createElement("canvas");
canvas.setAttribute("id","pdfCanvas"+num);
canvas.setAttribute("onclick","popCanvas('{{url('/dashboard/showcanvas')}}','"+document.getElementById('pdfPath').innerHTML+"','"+num+"');");
var ctx = canvas.getContext('2d');
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
if(currPageNum() === 1) {
height = viewport.height;
width = viewport.width;
}
canvas.height = height;
canvas.width = width;
canvasContainer.appendChild(canvas);
page.render(renderContext).then(function() {
def.resolve();
});
})
return def.promise();
}
function renderPages(data) {
pdfDoc = data;
var pagesCount = pdfDoc.numPages;
for (var i = 1; i <= pagesCount; i++) {
func = renderPage;
promise = promise.then(makeRunner(func, i));
}
}
PDFJS.disableWorker = true;
PDFJS.getDocument(url).then(renderPages);
};
var body = document.getElementById("bodyofpdf");
renderPDF(filePath, body);
});
When I change the filepath url, for example: "https://www.tutorialspoint.com/bootstrap/bootstrap_tutorial.pdf", it works.
Can somebody help me ??
Sorry for my poor english.
If you are using Laravel you can control the behaviour of the routes, including the one to a .pdf. For local files, browsers have a different behaviour by default than for no local files.
I have used a lot PDF.js and I don't know why do you link the user directly to the file, you could create like a view page where it gets a parameter like the id or the name of the book and then you load it with pdf.js. If you use an url with a file extension you will probably confuse the browser.
yourpage.com/books/view/{id_book}

How to register Window phone with notification hub in app-backend

Hello friends i am trying to implement the app-backend registration of app with notification hub.for implementing it i am following this notify user with notification hub but i wanted to do registration for windows phone so i have tried to do it and write this code in mobile service Api
exports.post = function(request, response) {
// Use "request.service" to access features of your mobile service, e.g.:
// var tables = request.service.tables;
// var push = request.service.push;
var azure = require('azure');
var hub = azure.createNotificationHubService('samplenotificationhub',
'full access key');
var platform = request.body.platform;
var installationId = request.header('X-ZUMO-INSTALLATION-ID');
var registrationComplete = function(error, registration) {
if (!error) {
// Return the registration.
response.send(200, registration);
} else {
response.send(500, 'Registration failed!');
}
}
// Function called to log errors.
var logErrors = function(error) {
if (error) {
console.error(error)
}
}
hub.listRegistrationsByTag(installationId, function(error, existingRegs) {
var firstRegistration = true;
if (existingRegs.length > 0) {
for (var i = 0; i < existingRegs.length; i++) {
if (firstRegistration) {
// Update an existing registration.
if (platform === 'wp') {
existingRegs[i].ChannelUri = request.body.channelUri;
hub.updateRegistration(existingRegs[i], registrationComplete);
} else {
response.send(500, 'Unknown client.');
}
firstRegistration = false;
} else {
// We shouldn't have any extra registrations; delete if we do.
hub.deleteRegistration(existingRegs[i].RegistrationId, logErrors);
}
}
} else {
// Create a new registration.
if (platform === 'wp') {
hub.mpns.createNativeRegistration(request.body.channelUri,
[request.body.CurrentDate], registrationComplete);
}
else {
response.send(500, 'Unknown client.');
}
}
});
};
i am able to get the api call from this code in my app..
private async Task AcquirePushChannel()
{
CurrentChannel = HttpNotificationChannel.Find("mychannel");
string message;
if (CurrentChannel == null)
{
CurrentChannel = new HttpNotificationChannel("mychannel");
CurrentChannel.Open();
CurrentChannel.BindToShellTile();
CurrentChannel.BindToShellToast();
}
var body = new NotificationRequest
{
channelUri = CurrentChannel.ChannelUri.ToString(),
platform = "wp",
CurrentDate = "1",
};
try
{
// Call the custom API POST method with the supplied body.
var result = await App.MobileService
.InvokeApiAsync<NotificationRequest,
RegistrationResult>("registrationapi", body,
System.Net.Http.HttpMethod.Post, null);
// Set the response, which is the ID of the registration.
message = string.Format("Registration ID: {0}", result.RegistrationId);
registrationid = result.RegistrationId;
}
catch (MobileServiceInvalidOperationException ex)
{
message = ex.Message;
}
i have seen an active api call on mobile service dashboard but not able to get response from API..
i have written this code in my table scripts so that i can send push notification to my phone it..also take a look if anything is wrong in it.
function insert(item, user, request) {
var azure = require('azure');
var hub = azure.createNotificationHubService('samplenotificationhub',
'listen signature string');
// Create the payload for a Windows Store app.
var wnsPayload = '<toast><visual><binding template="ToastText02"><text id="1">New item added:</text><text id="2">' + "tanuj" + '</text></binding></visual></toast>';
var Toasttemplate = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<wp:Notification xmlns:wp=\"WPNotification\">" +"<wp:Toast>" +"<wp:Text1>$(" + "1" + ")</wp:Text1>" +"</wp:Toast> " +"</wp:Notification>";
// Execute the request and send notifications.
request.execute({
success: function() {
// Write the default response and send a notification
// to the user on all devices by using the userId tag.
request.respond();
hub.wpns.send("1", Toasttemplate, 'wpns/toast', function(error) {
if (error) {
console.log(error);
}
});
}
});
i know this is lot of code i am putting this because the link is not mentioned for wp so just wanted to make sure i am doing right.
also please let me know first what is INSTALATIONID in var installationId = request.header('X-ZUMO-INSTALLATION-ID'); hope to get some response. any help ,idea or suggestion is appreciated.

Resources