I am trying to call the Microsoft Cognitive API by passing multiple images as per documentation and using the multipart/form-data, but I am getting an error that says "Unsupported Media Type". I have tried to use both ByteArray and StreamContent.
Api documentation.
private static byte[] GetImageAsByteArray(Stream fileStream)
{
using (var binaryReader = new BinaryReader(fileStream))
{
return binaryReader.ReadBytes((int)fileStream.Length);
}
}
static void Main(string[] args)
{
var uriBase = "https://westus.api.cognitive.microsoft.com/vision/v1.0/recognizeText";
var subscriptionKey = "<subscriptionKey>";
var client = new HttpClient();
var uri = string.Concat(uriBase, "?", "language=en&detectOrientation=true");
var images = new List<Stream>();
var img = Image.FromStream(File.Open("<imageName>", FileMode.Open));
var stream = new MemoryStream();
img.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
images.Add(stream);
using (var content = new MultipartFormDataContent())
{
foreach (var image in images)
{
//content.Add(new StreamContent(stream));
content.Add(new ByteArrayContent(GetImageAsByteArray(image)));
}
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
var response = client.PostAsync(uri, content).Result;
}
}
I am trying to call the Microsoft Cognitive API by passing multiple images as per documentation and using the multipart/form-data, but I am getting an error that says "Unsupported Media Type".
It is not possible to send multiple images, regardless of header.
Please refer to the documentation Step 2, it mentions:
The basic way to perform the Computer Vision API call is by uploading an image directly. This is done by sending a "POST" request with application/octet-stream content type together with the data read from the image.
Example code can be found here
Test environment here.
Notice regardless of header, it is still sending 1 image.
The limits also mention a single image.
Related
I want to create a Azure DevOps Attachment. The attachment is an Outlook message.
From the documentation seen here.
The body must be "[BINARY FILE CONTENT]". How can I read a .msg-File into C# and add it to a JsonBody Request?
Had to do something like this recently, the code looks like the stuff below.
The byte[] is the data i read directly from the filestream, like so
byte[] bytes;
using (var img = File.OpenRead("message.msg"))
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
bytes = memoryStream.ToArray();
}
}
then posting it to Azure DevOps
internal async Task<Attachement> UploadAttachment(string filename,byte[] content)
{
ByteArrayContent data = new ByteArrayContent(content);
HttpClient client = GetApiClient();
using (HttpResponseMessage response = await client.PostAsync($"https://dev.azure.com/{_org}/_apis/wit/attachments?fileName={filename}&api-version=5.1", data))
{
// Parse response body en evaluate result
var responseBody = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Attachement>(responseBody);
}
}
This seems to work quit well for us :)
don't forget to also actually add it to the workitem using: https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/work%20items/update?view=azure-devops-rest-5.1#add-an-attachment
I need to make a POST call from my Xamarin forms app where I need to upload a file object as it is to API using POST Call. Is there any way to make it possible?
if you send file object using Base64 or Byte[] then it will allowed only limited may be upto 2-4 Mb but if you have a larger image than that it will not support.
So, Solution is Post Stream Content Like,
var file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.Full,
CompressionQuality = 100
});
Create Object of MediaFile like, public MediaFile AttachedImage; and Store file into it so Memory stream will not lost. Like,AttachedImage = file
Post Code on API,
HttpClient httpClient = new HttpClient();
MultipartFormDataContent mt = new MultipartFormDataContent();
AttachedImage.GetStream().Position = 0;
StreamContent imagePart = new StreamContent(AttachedImage.GetStream());
imagePart.Headers.Add("Content-Type", ImageType);
mt.Add(imagePart, String.Format("file"), String.Format("bk.jpeg"));
requestMessage.Content = mt;
var response = await httpClient.PostAsync("Your URL", mt);
if (response.IsSuccessStatusCode)
{
var responseString = await response.Content.ReadAsStringAsync();
var objRootObjectuploadImage = JsonConvert.DeserializeObject<RootObjectuploadImage>(responseString);
if (objRootObjectuploadImage != null)
{
}
else
{
}
}
else
{
Loading(ActIndicator, false);
await DisplayAlert(res.LAlert, "webserver not responding.", res.LOk);
}
NO, it is not possible to send file object. You can send as a json by converting the file in the Base64 string. This is the advised proven solution. This link has code for converting back and forth from Base64.
I'm trying to upload an .mp4 file to Giphy.com's API. It says to send the file over as 'Binary' and I think I'm confused as what exactly they mean by that. Here's the docs if you scroll to the bottom at "Upload Endpoint". https://developers.giphy.com/docs/
Here's what I have right now.
I've tried multiple versions of this (using StringContent, MultipartFormDataContent, ByteArrayContent, HttpMessages... etc) and always get a '400 - Bad Request - No Source Url' (which the docs say isn't required if you upload you're own) which makes me believe the content isn't being recognized.
public async Task<HttpResponseMessage> UploadVideoAsync(StorageFile file)
{
using (var stream = await file.OpenStreamForReadAsync())
{
byte[] bytes = new byte[stream.Length];
await stream.ReadAsync(bytes, 0, (int)stream.Length);
Dictionary<string, string> dic = new Dictionary<string, string>
{
{ "file", Encoding.ASCII.GetString(bytes) },
{ "api_key", api_key }
};
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(bytes));
var response = await httpClient.PostAsync($"v1/gifs?api_key={api_key}", multipartContent);
var stringResponse = await response.Content.ReadAsStringAsync();
return response;
}
}
It seems that your code doesn't match {api_key} properly. You don't use the "dic" variable anywhere. You can try with v1/gifs?api_key=YOUR_API_KEY&file= instead. Where YOUR_API_KEY should be replaced by your API key obtained from giphy.
always get a '400 - Bad Request - No Source Url' (which the docs say isn't required if you upload you're own) which makes me believe the content isn't being recognized.
You need to apply a name for the ByteArrayContent. The document has shown that Request Parameters contains 'file: string (binary) required if no source_image_url supplied'.
The code should like the following:
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(bytes),"file");
Using the code from the MS Cognitive services example app at https://learn.microsoft.com/en-us/azure/cognitive-services/computer-vision/quickstarts/csharp I get Error 404 when trying to run the following code with imageFilePath set a local JPEG file:
static async void MakeAnalysisRequest(string imageFilePath)
{
HttpClient client = new HttpClient();
// Request headers.
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
// Request parameters. A third optional parameter is "details".
string requestParameters = "visualFeatures=Description&language=en";
// Assemble the URI for the REST API Call.
string uri = uriBase + "?" + requestParameters;
HttpResponseMessage response;
// Request body. Posts a locally stored JPEG image.
byte[] byteData = GetImageAsByteArray(imageFilePath);
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
// This example uses content type "application/octet-stream".
// The other content types you can use are "application/json" and "multipart/form-data".
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// Execute the REST API call.
response = await client.PostAsync(uri, content);
// Get the JSON response.
string contentString = await response.Content.ReadAsStringAsync();
// Display the JSON response.
Console.WriteLine("\nResponse:\n");
Console.WriteLine(JsonPrettyPrint(contentString));
}
subscriptionKey is KEY1 from the two keys provided with my Azure subscription (in Eastern Australia location) and uribase is
const string uriBase = "https://australiaeast.api.cognitive.microsoft.com/vision/v1.0";
The combination of KEY1 and uriBase works OK with the demo of the API at
https://australiaeast.dev.cognitive.microsoft.com/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fa/console
when the target file is a URL rather than a local file. The image is correctly analyzed.
Why am I getting the 404 error when trying to post from C#? Is it the fact that I am using content type application/octet-stream?
Code for GetImageAsByteArray is:
static byte[] GetImageAsByteArray(string imageFilePath)
{
FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read);
BinaryReader binaryReader = new BinaryReader(fileStream);
return binaryReader.ReadBytes((int)fileStream.Length);
}
You're missing the last portion of the request URI. It should be:
string uri = uriBase + "/analyze?" + requestParameters;
I am trying to use Tweetsharp's SendTweetWithMedia with a image which I don't have stored locally, I only have a url. All the examples I have found of SendTweetWithMedia use a file on the local system.
var thumb = "http://somesite.net/imageurl";
var service = new TwitterService(key, secret);
service.AuthenticateWith(token, tokenSecret);
var req = WebRequest.Create(thumb);
using (var stream = req.GetResponse().GetResponseStream())
{
response = service.SendTweetWithMedia(new SendTweetWithMediaOptions
{
Status = tweet.Trim(),
Images = new Dictionary<string, Stream> { { fullname, stream } }
});
}
I get the following error from SendTweetWithMedia:
'System.NotSupportedException': This stream does not support seek operations.
I could download the file from the url and save locally, but I'd rather use the url. Is this possible?
In the end, I just created a temporary file:
byte[] data;
using (var client = new WebClient())
{
data = client.DownloadData(thumb);
}
File.WriteAllBytes($"{Path.GetTempPath()}\\xyz.jpg", data);
best answer I could come up with. Still a few more lines than I'd like though.