Using image handler to convert relative path to absolute.
protected byte[] ConvertHTMLToPDF(string HTMLCode)
{
if (Request.Url == null)
throw new Exception();
var doc = new Document(PageSize.A4);
doc.Open();
var interfaceProps = new Hashtable();
var ih = new ImageHander {BaseUri = Request.Url.ToString()};
interfaceProps.Add("img_provider", ih);
foreach (IElement element in HTMLWorker.ParseToList(new StringReader(HTMLCode), null, interfaceProps))
{
doc.Add(element);
}
var _xmlr = new XmlTextReader(new StringReader(HTMLCode));
HtmlParser.Parse(doc, _xmlr);
var stream = new MemoryStream();
PdfWriter.GetInstance(doc, stream);
doc.Close();
return stream.ToArray();
}
class:
public class ImageHander : IImageProvider
{
public string BaseUri;
public Image GetImage(string src, Hashtable h, ChainedProperties cprops, IDocListener doc)
{
string imgPath;
if (src.ToLower().Contains("http://") == false)
imgPath = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + src;
else
imgPath = src;
return Image.GetInstance(imgPath);
}
}
imgPath at the end is correct. But it's not static file, it's url of action that returns image, so I need to pass cookies when requesting image. Is it possible?
Yes, it is possible, but you're gonna have to send the request yourself and not rely on the Image.GetInstance method. For example using the HttpClient you could send cookies along with the request:
var imageUrl = new Uri(imagePath);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler))
{
cookieContainer.Add(
new Uri(imageUrl.GetLeftPart(UriPartial.Authority)),
new Cookie("CookieName", "cookie_value")
);
var response = client.GetAsync(imageUrl).Result;
response.EnsureSuccessStatusCode();
Stream imageStream = response.Content.ReadAsStreamAsync().Result;
// You've got the Stream here, read the documentation of iTextSharp
// how to create an Image instance from a Stream:
return Image.FromStream(imageStream); // ?????
// or maybe there's a method allowing you to create an Image from byte[]
byte[] imageData = new byte[imageStream.Length];
imageStream.Read(imageData, 0, imageData.Length);
return Image.FromByteArray(imageData); // ?????
}
Related
In my xamarin.forms app. I am using Media.plugin to select images from gallery and camera.And also file picker plugin to select files like pdf,jpg etc from file manager.User can select multiple images and files and It will store in an observable collection.In this observable collection I have the path of images as well as files. Where I am stuck is I want to send these data to rest API by using multipart/form data.How can I send these multiple files to the server? Any help is appreciated.
My ObservableCollection
public ObservableCollection<SelectedDocumentModel> DataManager
{
get
{
return _selectedfile ?? (_selectedfile = new ObservableCollection<SelectedDocumentModel>());
}
}
My Data Model
public class SelectedDocumentModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string FileName { get; set; }
public string Path { get; set; }
public ImageSource SelectedImage { get; set; }
public object Tasks { get; internal set; }
private bool isLoadingVisible = false;
public bool IsLoadingVisible
{
get
{
return isLoadingVisible;
}
set
{
if (value != null)
{
isLoadingVisible = value;
NotifyPropertyChanged("IsLoadingVisible");
}
}
}
}
Selecting image using media.plugin and allocating to my observable collection
var Filename = Path.GetFileName(file.Path);
var FilePath = file.Path;
var newList = new SelectedDocumentModel()
{
FileName = Filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path = FilePath
};
DataManager.Add(newList);
Selecting file from file manager using filepicker plugin and assign to observablecollection
var FilePath = pickedFile.FilePath;
var newList = new SelectedDocumentModel()
{
FileName = filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path= FilePath
};
DataManager.Add(newList);
EDIT
This is what I should do using httpclient.Currently these are written using RestSharp.
var client = new RestClient("{{api_url}}/MYData");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "bearer {{token}}");
request.AddHeader("Content-Type", "application/json");
request.AlwaysMultipartFormData = true;
request.AddParameter("ids", " [{\"id\":1,\"person_id\":5}]");
request.AddParameter("title", " Test");
request.AddParameter("description", " Test");
request.AddParameter("send_text_message", " true");
request.AddParameter("text_message", " Test");
request.AddParameter("notification_type"," global");
request.AddParameter("my_files", "[
{
\"name\": \"abc.jpg\",
\"key\": \"1583307983694\"
}
]");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
What I have done by the way suggested by Lucas Zhang - MSFT.
try {
MultipartFormDataContent multiContent = new MultipartFormDataContent();
foreach (SelectedDocumentModel model in SelectedFileData)
{
byte[] byteArray = Encoding.UTF8.GetBytes(model.Path);
MemoryStream stream = new MemoryStream(byteArray);
HttpContent fileStreamContent1 = new StreamContent(stream);
fileStreamContent1.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = model.FileName,
FileName = model.FileName
};
fileStreamContent1.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
multiContent.Add(fileStreamContent1);
}
multiContent.Add(new StringContent(notificationdetails[0]), "title");
multiContent.Add(new StringContent(notificationdetails[1]), "description");
multiContent.Add(new StringContent(notificationdetails[3]), "type");
multiContent.Add(new StringContent(notificationdetails[7]), "send_text_message");
multiContent.Add(new StringContent(notificationdetails[2]), "text_message");
multiContent.Add(new StringContent(notificationdetails[8]), "send_email");
multiContent.Add(new StringContent(notificationdetails[9]), "notification_type");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer",Settings.AuthToken);
var response = await client.PostAsync(url, multiContent);
var responsestr = response.Content.ReadAsStringAsync().Result;
await DisplayAlert("Result", responsestr.ToString(), "ok");
}
catch (Exception ex)
{
await DisplayAlert("Result", ex.Message.ToString(), "ok");
}
unfortunately it not working.It not sending the data as I intend.
How can I upload each files as multipart/formdata on a button click.?Any help is appriciated.
You could use MultipartFormDataContent to add multiple images,and use ContentDispositionHeaderValue.Parameters to add the values of your Data.
Usage
var fileStream = pickedFile.GetStream();
var newList = new SelectedDocumentModel()
{
FileName = filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path= FilePath,
Data = fileStream ,
};
MultipartFormDataContent multiContent = new MultipartFormDataContent();
foreach(var SelectedDocumentModel model in DataManager)
{
HttpContent fileStreamContent1 = new StreamContent(model.Data);
fileStreamContent1.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = "File",
FileName = "xxx.jpg"
};
fileStreamContent1.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
multiContent.Add(fileStreamContent1);
multiContent.Add(new StringContent(model.Title), "model.Title");
multiContent.Add(new StringContent(model.Description), "model.Description");
multiContent.Add(new StringContent(model.Detail), "model.Detail");
}
// Send (url = url of api) ,use httpclient
var response = await client.PostAsync(url, multiContent);
I have an upload function in my WebApi C# code, which works fine with Query string parameters. I will be passing the file in Rest client using multi-Form data and it works completely fine.
Now I have to change the parameters to JSON format, doing so the request is not hitting the controller. Can anyone please help me here.
public ReturnMsg UploadDocument(string fileName, string fileSize, string ApplNo, string DocId, string DocSize,string resumeId,string DependId)
{
ReturnMsg objReturnMsg = new ReturnMsg ();
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
Stream stream = null;
if (httpRequest.Files.Count > 0)
{
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = string.Empty;
stream = postedFile.InputStream;
}
objReturnMsg = Bll.UploadFiles(fileName, fileSize, DocId, DocSize,DependId,stream);
}
else
{
objReturnMsg.Status = "F";
objReturnMsg.ReturnMessage = "Please Upload a Valid Form";
}
return objReturnMsg;
}
I want it in
public ReturnMsg UploadDocument(DocDetails docDet)
{
ReturnMsg objReturnMsg = new ReturnMsg ();
HttpResponseMessage response = new HttpResponseMessage();
var httpRequest = HttpContext.Current.Request;
Stream stream = null;
if (httpRequest.Files.Count > 0)
{
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = string.Empty;
stream = postedFile.InputStream;
}
objReturnMsg = Bll.UploadFiles(docDet.fileName, docDet.fileSize, docDet.DocId, docDet.DocSize,docDet.DependId,stream);
}
else
{
objReturnMsg.Status = "F";
objReturnMsg.ReturnMessage = "Please Upload a Valid Form";
}
return objReturnMsg;
}
I have tried to read IMB barcode from an image with the below code snippet, but it always return null. I have also tried with the IMB barcode images in the blackbox testing below, but doesn't work.
https://github.com/micjahn/ZXing.Net/tree/master/Source/test/data/blackbox/imb-1
private static void Decode()
{
Bitmap bitmap = new Bitmap(#"\07.png");
try
{
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
byte[] byteArray = memoryStream.GetBuffer();
ZXing.LuminanceSource source = new RGBLuminanceSource(byteArray, bitmap.Width, bitmap.Height);
var binarizer = new HybridBinarizer(source);
var binBitmap = new BinaryBitmap(binarizer);
IMBReader imbReader = new IMBReader();
Result str = imbReader.decode(binBitmap);
}
catch { }
}
I have solved this problem by using the below code snippet shared through the below link.
https://github.com/micjahn/ZXing.Net/issues/59
private static void Decode2()
{
var bitmap = new Bitmap(#"\07.png"); // make sure that the file exists at the root level
try
{
var imbReader = new BarcodeReader
{
Options =
{
PossibleFormats = new List<BarcodeFormat> {BarcodeFormat.IMB}
}
};
var result = imbReader.Decode(bitmap);
if (result != null)
System.Console.WriteLine(result.Text);
else
System.Console.WriteLine("nothing found");
}
catch (System.Exception exc)
{
System.Console.WriteLine(exc.ToString());
}
}
Call Rest service
Rest service returns byte[] representation of image/audio/video
convert into byte[] to image and show in content page in xamarin
First of all, you can create a function that simply makes an API request and obtains the content in the form of byte array. A simple example of HTTP request:
public static byte[] GetImageByteArray(string url)
{
try
{
using (var client = new HttpClient())
{
var uri = new Uri(url);
var response = client.GetAsync(uri).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsByteArrayAsync();
return content.Result;
}
}
return null;
}
catch
{
return null;
}
}
Next, you can simply bind the output from your result into your image source and the image to your content:
var mainStack = new StackLayout();
var imageByteArray = GetImageByteArray("https://static.pexels.com/photos/34950/pexels-photo.jpg");
Image image;
if (imageByteArray != null)
{
image = new Image()
{
Source = ImageSource.FromStream(() => new MemoryStream(imageByteArray))
};
mainStack.Children.Add(image);
}
Content = mainStack;
I need to display an image as if using normal HTML, but I can't provide a normal url to the image for security reasons. Instead I need to retrieve the image from a WebApi service. I found this:
https://stackoverflow.com/a/24985886/1481314
And, I've looked at the links provided in the answers, but something isn't working. All I'm getting is a missing image placeholder.
This is my code - client-side:
angular.element('#' + imageType + '_' + itemID).html('<img src="/api/filemanagermaindata/getFile?systemName=' + baseData.CustomerData.SystemName + '&fileID=' + id + '" />')
This is my WebApi Controller Method
[HttpGet]
[Route("api/filemanagermaindata/getFile")]
public HttpResponseMessage GetFile(string systemName, int fileID)
{
var customerData = ValidateUser(systemName, 0);
var response = this.fileMover.GetFileDataHttpResponse(customerData.OrganizationID, fileID);
return response;
}
And my class method that gets and returns the image...
var response = new HttpResponseMessage();
try
{
FileManagerItem item = this.dataService.GetFileByID(fileID);
var fullPath = this.rootLocation + Path.Combine( item.PhysicalPath, item.Name);
if (!File.Exists(fullPath))
{
throw new Exception("Unable to locate the requested file");
}
var fileType = Path.GetExtension(item.Name).Replace(".", string.Empty);
if (ApplicationSettings.Instance.ImageFileExtensions.Contains(fileType))
{
fileType = string.Format("image/{0}", fileType);
}
using (FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read))
{
response = new HttpResponseMessage { Content = new StreamContent(fileStream) };
response.Content.Headers.ContentType = new MediaTypeHeaderValue(fileType);
response.Content.Headers.ContentLength = fileStream.Length;
};
return response;
}
Dumb mistake. The using {} block was killing the FileStream before the data was loaded.