I need to render svg in my XSL fo in c#.Net which is available in https://fonet.codeplex.com/. I tried to use svg in the xsl-fo but it does not render any pdf and fails silently.
If anybody has found a solution for this issue please help.
I need my pdf report to support svg contents.
Use the below code to add Hander of an image incase of svg extensions
FonetDriver fonetDriver = FonetDriver.Make();
fonetDriver.ImageHandler = SvgImageHandler;
Add the SvgImageHandler Hander
private static byte[] SvgImageHandler(string svgContent)
{
if (svgContent.Contains("http://www.w3.org/2000/svg"))
{
var svgByteAry = Encoding.UTF8.GetBytes(svgContent);
using (var stream = new MemoryStream(svgByteAry))
{
var svgDocument = SvgDocument.Open<SvgDocument>(stream);
using (var memoryStream = new MemoryStream())
{
svgDocument.Draw()
.Save(memoryStream, ImageFormat.Png);
var byteArray = memoryStream.ToArray();
return byteArray;
}
}
}
//Skip if not url based image
if (!Uri.IsWellFormedUriString(svgContent, UriKind.RelativeOrAbsolute))
return null;
if (!ValidateUrlImage(svgContent))
{
ICacheService cacheService = new HttpCache();
return cacheService.Get(Constants.NoImage,
() =>
{
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings[Constants.ImagePath];
var defaultUrl = Path.Combine(baseDirectory, Constants.NoImageFile);
var img = Image.FromFile(defaultUrl);
var imgCon = new ImageConverter();
return (byte[])imgCon.ConvertTo(img, typeof(byte[]));
});
}
return null;
}
Return proper image if the url is valid or pass false so the No Image can be rendered. keeping the code more robust.
private static bool ValidateUrlImage(string absoluteUrl)
{
Uri uri;
if (!Uri.TryCreate(absoluteUrl, UriKind.Absolute, out uri))
{
return true;
}
using (var client = new WebClient())
{
try
{
using (var stream = client.OpenRead(uri))
{
Image.FromStream(stream);
return true;
}
}
catch (Exception)
{
return false;
}
}
}
Related
I have an API written in asp.net core 5. There I have a controller that receive a IFile object. Everything is fine till I need on the end of the process to save the file on the local hard drive. There my path named formatedPath is correct and it contains the full path (like: D:/tanulmanyiversenyek.hu/server/profile/8226dfa5-2743aiE2-45cfpTjG-b186yENr-167280a987aa.png).
But when the save is called I god an exception with error message:
D:\tanulmanyiversenyek.hu\server\profile of the filename D:/tanulmanyiversenyek.hu/server/profile/8226dfa5-2743aiE2-45cfpTjG-b186yENr-167280a987aa.png
The bolder part is added somehow. I can't figure out why.
[Route("api/v{version:apiVersion}/image/profile")]
[ApiVersion(ApplicationSettingsConstans.ActiveVersion)]
[HttpPost]
[AllowAnonymous]
[ProducesResponseType((int)HttpResponseType.OK, Type = typeof(string))]
[ProducesResponseType((int)HttpResponseType.BadRequest)]
[Produces("application/json")]
public async Task<string> UploadProfileImageAsync([FromForm] IFormFile file)
{
ServiceResponse<string> request = await _imageUploadService.UploadProfileImageAsync(file);
if (!request.IsSuccess)
{
throw new Exception(request.Message);
}
return request.ResultObject;
}
public async Task<ServiceResponse<string>> UploadProfileImageAsync(IFormFile file)
{
ServiceResponse<string> response = new ServiceResponse<string>();
try
{
response.ResultObject = await ImageUploadHandler.SaveProfileImageAsync(file);
}
catch (Exception ex)
{
response.IsSuccess = false;
response.Message = ex.Message;
response.ResultObject = string.Empty;
}
return response;
}
public static async Task<string> SaveProfileImageAsync(IFormFile file)
{
if (file.Length < 1)
{
return null;
}
string result = string.Empty;
string extension = file.FileName.Reverse().Split(".")[0].Reverse();
string fileName = $"{GenerateName()}.{extension}";
string subFolder = UploadedFileType.Profile.ToString().ToLower();
#if DEBUG
string path = $#"{ServerPathEnviorement.Base()}\{subFolder}\{fileName}";
result = $#"\{subFolder}\{fileName}";
#else
string path = $#"{ServerPathEnviorement.Base()}/{subFolder}/{fileName}";
result = $#"/{subFolder}/{fileName}";
#endif
await SaveOnDisk(path, file, 720, 405);
return result;
}
private static async Task SaveOnDisk(string path, IFormFile file, int width = 1920, int height = 1080)
{
string formatedPath = path.Replace(#"/", #"\");
Image image = null;
using (MemoryStream memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream);
image = Image.FromStream(memoryStream);
}
using (Bitmap bitmap = new Bitmap(image))
{
byte[] data = ImageCompressor.ScaleImage(bitmap, width, height, false);
using (MemoryStream memoryStream = new MemoryStream(data))
{
image = Image.FromStream(memoryStream);
image.Save(formatedPath, ImageFormat.Jpeg); *//error thrown here*
}
}
The same error appears form Postman or from my react app.
Interesting think is if I repleace the formatedPath variable with direct path to file like: d:/tanulmanyiversenyek.hu/server/profile/167280a987aa.png it is working !
I am trying to save an image from the Android gallery to a shared folder on a windows server. With the NuGet SharpCifs.Std package installed, I try to use the CopyTo method to save the image but it gives an error when the path is correct to my knowledge.
This is the error
Piece of code ...
using SharpCifs.Smb;
...
...
var windowsAuth = new NtlmPasswordAuthentication("mydomain.local", "user", "password");
var source = new SmbFile(photoFile);
var dest = new SmbFile(photosPath, windowsAuth);
source.CopyTo(dest);
In debug mode, the value of variables are:
source = file:///storage/emulated/0/Android/data/com.salicru/files/Pictures/temp/IMG_20190828_101004_88.jpg
dest = file://srvdoc/compartit/fotos equips/M3/6A0BW000001/
What am I doing wrong?
I had to create a method that I called ConvertMediaFileToByteArray for the conversion of the photo stream to a byte[].
private byte[] ConvertMediaFileToByteArray(MediaFile file)
{
using (var memoryStream = new MemoryStream())
{
file.GetStream().CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
Converting call.
file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.Small
});
if (file != null)
{
imageSource = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
//Convert ImatgeStream to BYTE[]
var imageToByte = ConvertMediaFileToByteArray(file);
}
Then, instead of using CopyTo method i used CreateNewFile method.
var windowsAuth = new NtlmPasswordAuthentication("domain", "admin", "password");
var dest = new SmbFile(photosPath + imageName, windowsAuth);
dest.CreateNewFile();
var writeStream = dest.GetOutputStream();
writeStream.Write(imageToByte);
writeStream.Dispose();
I'm developing an mobile application using Xamarin Forms where in an app send an image to server. For sending image we've used WCF services.
Well below is the code for Xamarin Application
using (var memoryStream = new MemoryStream())
{
pick.GetStream().CopyTo(memoryStream);
pick.Dispose();
byte[] byteImageArray = memoryStream.ToArray();
try
{
var imageStream = new ByteArrayContent(byteImageArray);
var multi = new MultipartContent();
multi.Add(imageStream);
var client = new HttpClient();
var result = client.PostAsync("http://www.test.com/Services/Service.svc/SaveImage", multi).Result;
var json = await result.Content.ReadAsStringAsync();
var strNo = JsonConvert.DeserializeObject<string>(json);
}
catch (Exception ex)
{
await DisplayAlert("Error", ex.Message, "Ok");
}
}
And for WCF services
public string SaveImage(Stream data)
{
byte[] byteImage = ReadFully(data);
//Database logic to insert byte array
}
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
Now with this code image is getting converted successfully and getting stored in database blob.
Issue I'm facing is whenever I convert blob back to image, the image gets corrupted. When I insert image into blob with asp.net application the data length of blob is displayed as 18901 whereas while inserting same image with mobile application data length is 18987.
Please help me to resolve the data length issue, or please guide easier way to store image into data base using WCF and Xamarin forms.
Create an WebAPI called PicturesController for example. You must use PUT verb
/// <summary>
/// Receiving an image across WebAPI
/// </summary>
/// <returns></returns>
[HttpPut]
public HttpResponseMessage Put()
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
try
{
Request.Content.LoadIntoBufferAsync().Wait();
Request.Content.ReadAsMultipartAsync<MultipartMemoryStreamProvider>(
new MultipartMemoryStreamProvider()).ContinueWith((task) => {
MultipartMemoryStreamProvider provider = task.Result;
foreach (HttpContent content in provider.Contents)
{
Stream stream = content.ReadAsStreamAsync().Result;
Image image = Image.FromStream(stream);
try
{
string filename = string.Format("{0}{1}{2}{3}",
DateTime.Now.Year,
DateTime.Now.Month,
DateTime.Now.Day,
DateTime.Now.Second) + ".jpg";
foreach (var h in content.Headers.ContentDisposition.Parameters)
{
if (h.Name.ToLower() == "filename")
{
filename = h.Value.Replace("\\", "/").Replace("\"", "");
var pos = filename.LastIndexOf("/");
if (pos >= 0)
{
filename = filename.Substring(pos + 1);
}
break;
}
}
string filePath = ConfigurationManager.AppSettings["Pictures"]
.ToString();
string fullPath = Path.Combine(filePath, filename);
EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(Encoder.Quality, 80L);
ImageCodecInfo ici = null;
foreach (ImageCodecInfo codec in ImageCodecInfo
.GetImageEncoders())
{
if (codec.MimeType == "image/jpeg")
{
ici = codec;
break;
}
}
image.JpegOrientation().Save(fullPath, ici, encparams);
}
catch (Exception ex)
{
}
}
});
}
catch (Exception ex)
{
result.StatusCode = HttpStatusCode.InternalServerError;
}
return result;
}
else
{
throw new HttpResponseException(Request.CreateResponse(
HttpStatusCode.NotAcceptable,
"This request is not properly formatted"));
}
}
In this code I create a temporary file name. If you pass one as header parameter, I use that. I save the image in a folder Pictures and I read this folder from web.config. The file is in jpeg format because usually this is the image format on your device.
When you do that, you have to create a webclient in your Xamarin project.
/// <summary>
/// Uploads the photo.
/// </summary>
/// <returns>The photo.</returns>
/// <param name="photoBytes">Photo bytes.</param>
public async Task<bool> UploadPhoto(byte[] photoBytes, int PropertyId, string fileName)
{
bool rtn = false;
var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(photoBytes);
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
fileContent.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") {
FileName = fileName + ".jpg"
};
content.Add(fileContent);
fileContent.Headers.ContentDisposition.Parameters.Add(
new NameValueHeaderValue("<otherParam>", "<otherParamValue>"));
string url = RestURL() + "Pictures/Put";
try
{
using (var client = new HttpClient())
{
// add an authotization token if you have one
//client.DefaultRequestHeaders.Add("authenticationToken", "yourToken");
await client.PutAsync(url, content);
rtn = true;
}
}
catch (Exception ex)
{
}
return rtn;
}
Remember to include
using System.Net.Http;
using System.Net.Http.Headers;
I'm using this implementation in a lot of apps and it's working perfectly. If you have any suggestion to improve it, tell me please.
Simply changing
var multi = new MultipartContent();
multi.Add(imageStream);
To
StreamContent scontent = new StreamContent(pick.GetStream());
HttpContent hp = scontent;
Resolved the issue. Hope I'm not going wrong anywhere.
Im using the following code to get the signature from the signature pad, But any value doesn't come.
try {
var signature = padView.GetImage (Acr.XamForms.SignaturePad.ImageFormatType.Png);
using (BinaryReader br = new BinaryReader (signature)) {
var result = br.ReadBytes ((int)signature.Length);
}
} catch (Exception ex) {
// Helper_ErrorHandling.SendErrorToServer (ex);
}
Am I ding it wrong, Also how do i convert this to a base64 string
?
I'm not too familiar with the Xamarin Forms Signature Pad, but if you're looking for a way to convert a Stream to as base64 string, try this:
[...]
string base64String;
using (var memoryStream = new MemoryStream())
{
signature.CopyTo( memoryStream );
var byteArray = memoryStream.ToArray();
base64String = Convert.ToBase64String( byteArray );
}
EDIT: you can most of the time skip the copy, if you check if signature is already a MemoryStream...
[...]
string base64String;
var signatureMemoryStream = signature as MemoryStream;
if (signatureMemoryStream == null)
{
signatureMemoryStream = new MemoryStream();
signature.CopyTo( signatureMemoryStream );
}
var byteArray = signatureMemoryStream.ToArray();
base64String = Convert.ToBase64String( byteArray );
Using the most current PCL compliant Xamarin package :
acr-xamarin-forms
This method works like a charm!
private string ConvertSignatureToBase64()
{
try
{
byte[] data;
if(Device.OS == TargetPlatform.iOS)
{
var img = SignaturePad.GetImage(Acr.XamForms.SignaturePad.ImageFormatType.Jpg);
var signatureMemoryStream = new MemoryStream();
img.CopyTo(signatureMemoryStream);
data = signatureMemoryStream.ToArray();
}
else
{
var img = SignaturePad.GetImage(Acr.XamForms.SignaturePad.ImageFormatType.Jpg);
var signatureMemoryStream = (MemoryStream)img;
data = signatureMemoryStream.ToArray();
}
return Convert.ToBase64String(data);
}
catch(Exception ex)
{
return ex.ToString();
}
}
How is it possible to export a pdf using FastReport.net and asp.net?
I would like to export the File in a Controller. I tried it this way supported on the FastReport Website:
public FileResult GetFile()
{
WebReport webReport = new WebReport();
// bind data
System.Data.DataSet dataSet = new System.Data.DataSet();
dataSet.ReadXml(report_path + "nwind.xml");
webReport.Report.RegisterData(dataSet, "NorthWind");
// load report
webReport.ReportFile = this.Server.MapPath("~/App_Data/report.frx");
// prepare report
webReport.Report.Prepare();
// save file in stream
Stream stream = new MemoryStream();
webReport.Report.Export(new PDFExport(), stream);
stream.Position = 0;
// return stream in browser
return File(stream, "application/zip", "report.pdf");
}
but then the size of the pdf is always 0 bytes.
Does someone know a solution to my problem?
Ok, now I found a solution. Just use the normal Report (not WebReport) and set WebMode to true. The other settings on pdf-Export are just for fun.
So, this will do the trick:
public FileResult GetFile(Dataset dataset1)
{
FastReport.Utils.Config.WebMode = true;
Report rep = new Report();
rep.Load(Request.PhysicalApplicationPath + "App_Data/report.frx");
rep.RegisterData(dataset1);
if (rep.Report.Prepare())
{
// Set PDF export props
FastReport.Export.Pdf.PDFExport pdfExport = new FastReport.Export.Pdf.PDFExport();
pdfExport.ShowProgress = false;
pdfExport.Subject = "Subject";
pdfExport.Title = "xxxxxxx";
pdfExport.Compressed = true;
pdfExport.AllowPrint = true;
pdfExport.EmbeddingFonts = true;
MemoryStream strm = new MemoryStream();
rep.Report.Export(pdfExport, strm);
rep.Dispose();
pdfExport.Dispose();
strm.Position = 0;
// return stream in browser
return File(strm, "application/pdf", "report.pdf");
}
else
{
return null;
}
}
It's a pity that such code templates are wrong on the official site of the developer.
Works for me in 2017.1
public void GetFile()
{
SetReport();
webReport.ExportPdf();
}
public void GetPrint()
{
SetReport();
webReport.Prepare();
webReport.PrintPdf();
}