How do I retrieve image properly using ParseFile? - c#

I'm using the following code to save an image
ParseFile file = null;
if (ProfileImage != null && ProfileImage.ContentLength > 0 && !string.IsNullOrEmpty(ProfileImage.FileName))
{
byte[] fileBytes = new byte[ProfileImage.ContentLength];
file = new ParseFile(ProfileImage.FileName, fileBytes);
await file.SaveAsync();
var player = new ParseObject("Player");
if(file != null)
{
player["ProfilePic"] = file;
}
await player.SaveAsync();
}
I'm trying to retrieve the image so I can display using the following code
ParseObject player = Task.Run(() =>
ParseObject.GetQuery("Player").WhereEqualTo("objectId", id).FirstOrDefaultAsync()).Result;
ParseFile profileImage = null;
string profileImageUrl = "";
if (player.ContainsKey("ProfilePic"))
{
profileImage = player.Get<ParseFile>("ProfilePic");
profileImageUrl = profileImage.Url.AbsoluteUri;
}
profileImageUrl have a correct url such as http://files.parsetfss.com/c8db8833-b04b-4877-8040-b70df1ec216c/tfss-11c442f3-6146-4316-a6c0-7c9a063d897e-Koala.jpg
However, the image is always broken. I'm trying to display the image using html tag and the image is always broken.

Your example image contains 762Kb of zero-bytes. I can't really see in your save method that you actually put content in the array either.
byte[] fileBytes = new byte[ProfileImage.ContentLength];
file = new ParseFile(ProfileImage.FileName, fileBytes);
await file.SaveAsync();
The code above creates an empty array of x bytes long and then you save it. You should put the picture bytes in there somehow. I can't tell from your code what type the ProfileImage object is, but i suppose you can get the content bytes from that object.

Related

Can't retrieve image from web in Xamarin forms

In the viewmodel of my page, I try to get an image to show. This image I get from one of our webservice. The image source is stored in ProductImage
string path = $#"http://www.MyCompany.be/cdn-cgi/image/width=150,quality=75/images/products/{CurrentProduct.Image}".Replace($"\\", $"/");
ProductImage = ImageSource.FromUri(new Uri(path));
I of course make sure when I update the Image source for the view when I change it
public ImageSource ProductImage
{
get
{
return _productImage;
}
set
{
if (_productImage != value)
{
_productImage = value;
OnPropertyChanged();
}
}
}
Sadly, for some reason it doesn't work. I checked the URL called and it does lead to an image.
It used to work when I was using streams instead of calling an URL. I know I haven't put the safety checks around yet to make sure the image exist, but other than that nothing has changed. I save the image the exact same way, i just use fromUri rather than fromStream.
//Get target's SmbFile.
var file = new SmbFile(path, auth);
try
{
if (file.Exists())
{
// Get readable stream.
var readStream = file.GetInputStream();
//Create reading buffer.
MemoryStream memStream = new MemoryStream();
//Get bytes.
((Stream)readStream).CopyTo(memStream);
var stream1 = new MemoryStream(memStream.ToArray());
if (stream1.Length < 30000000)
{
//Save image
//ProductImage = ImageSource.FromStream(() => stream1);
//Dispose readable stream.
readStream.Dispose();
InfoColSpan = 1;
}
else
{
Common.AlertError("Image trop lourde pour l'affichage");
}
}
}
catch (Exception ex)
{
Common.AlertError(ex, "Impossible de charger l'image");
}
Since I changed my method, I no longer load anything.

How to pass xml file inside of code instead of a folder path?

I'am trying to not create a file, and pass xml document straight to a SkiaSharp method Load. I mean, is there the way to imitate a path? So here is the code:
public IActionResult svgToPng(string itemId, string mode = "
{
var svgSrc = new XmlDocument();
svgSrc.LoadXml(/*Some xml code*/);
string svgSaveAs = "save file path";
var quality = 100;
var svg = new SkiaSharp.Extended.Svg.SKSvg();
var pict = svg.Load(svgSrc); // HERE, it needs to be a path, not XmlDocument, but i want to pass straight
var dimen = new SkiaSharp.SKSizeI
(
(int) Math.Ceiling(pict.CullRect.Width),
(int) Math.Ceiling(pict.CullRect.Height)
);
var matrix = SKMatrix.MakeScale(1, 1);
var img = SKImage.FromPicture(pict, dimen, matrix);
// Convert to PNG
var skdata = img.Encode(SkiaSharp.SKEncodedImageFormat.Png, quality);
using(var stream = System.IO.File.OpenWrite(svgSaveAs))
{
skdata.SaveTo(stream);
}
ViewData["Content"] = "PNG file was created out of SVG.";
return View();
}
The Load method seems to be this:
public SKPicture Load(
using (var stream = File.OpenRead(filename))
{
return Load(stream);
}
}
look at the code of that library :
https://github.com/mono/SkiaSharp.Extended/blob/master/SkiaSharp.Extended.Svg/source/SkiaSharp.Extended.Svg.Shared/SKSvg.cs
Look at the Load method, it has multiple implementations :
public SKPicture Load(string filename)
{
using (var stream = File.OpenRead(filename))
{
return Load(stream);
}
}
public SKPicture Load(Stream stream)
{
using (var reader = XmlReader.Create(stream, xmlReaderSettings, CreateSvgXmlContext()))
{
return Load(reader);
}
}
public SKPicture Load(XmlReader reader)
{
return Load(XDocument.Load(reader));
}
You will need to pick one of them and use it. Now, nothing stops you from getting the code and adding one extra Load for an XML string for example, but since this is a library you do not control, I'd stick to what you are given.
You could use the XmlReader version, that's probably the closest one to what you want.

How to save image from clipboard to file in UWP

Is there any equivalent of
Clipboard.GetImage().Save(FileName, Imaging.ImageFormat.Jpeg)
for UWP (Windows Universal Platform)?
I.e. saving the graphics image from clipboard into jpg format to file.
I am looking for example in vb.net/C#.
I have already started with
Dim datapackage = DataTransfer.Clipboard.GetContent()
If datapackage.Contains(StandardDataFormats.Bitmap) Then
Dim r As Windows.Storage.Streams.RandomAccessStreamReference = Await datapackage.GetBitmapAsync()
...
but I do not know how to continue (and even if I have even started correctly).
The first step is to try and get the image from the clipboard, if it exists:
var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
if (dataPackageView.Contains(StandardDataFormats.Bitmap))
{
IRandomAccessStreamReference imageReceived = null;
try
{
imageReceived = await dataPackageView.GetBitmapAsync();
}
catch (Exception ex)
{
}
If it exists, launch a file save picker, choose where to save the image, and copy the image stream to the new file.
if (imageReceived != null)
{
using (var imageStream = await imageReceived.OpenReadAsync())
{
var fileSave = new FileSavePicker();
fileSave.FileTypeChoices.Add("Image", new string[] { ".jpg" });
var storageFile = await fileSave.PickSaveFileAsync();
using (var stream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
{
await imageStream.AsStreamForRead().CopyToAsync(stream.AsStreamForWrite());
}
}
}
}

Cannot deserialize Image after sending it through the network

So, I have these two methods, which I am using to serialize and deserialize Images:
private static Image GetImageFromString(string image)
{
using (var stream = new MemoryStream(Convert.FromBase64String(image)))
{
return Image.FromStream(stream);
}
}
private static string GetImageAsString(Image image)
{
using (var stream = new MemoryStream())
{
image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
return Convert.ToBase64String(stream.GetBuffer());
}
}
If I do something Like this:
public Form1()
{
InitializeComponent();
var image = Image.FromFile(#"F:\phpide.png");
pictureBox1.Image = image;
var serialized = GetImageAsString(image);
var secondImage = GetImageFromString(serialized);
pictureBox2.Image = secondImage;
}
It works as expected
Although, If I do something like this:
//client
public void GetImage(JObject o)
{
var imageFile = o["file"].ToString();
if (!File.Exists(imageFile))
{
SendMessage("File does not exist");
return;
}
using (var image = Image.FromFile(imageFile))
{
var serialized = GetImageAsString(image);
var ob = new JObject
{
{ COMMAND, (int) Command.GetImage },
{ "content", serialized }
};
Send(ob);
ob = null;
serialized = null;
}
}
//server
public void ReceiveImage(JObject o)
{
var content = o["content"].ToString();
var image = GetImageFromString(content);
var form = new ImagePreviewForm(image);
form.Show();
}
//server
public ImagePreviewForm(Image image)
{
InitializeComponent();
pictureBox1.Image = image;
}
The image is just blank.
I have checked and the image is being received correctly, with no data loss.
What could be going wrong here? Where should I look?
This is at least one problem:
return Convert.ToBase64String(stream.GetBuffer());
You shouldn't use MemoryStream.GetBuffer here - you should use ToArray. The GetBuffer method returns the underlying buffer as-is... complete with junk data at the end of the buffer, beyond the logical current length of the stream.
Additionally, you shouldn't close the stream when you call Image.FromStream. From the docs:
You must keep the stream open for the lifetime of the Image.
So get rid of the using statement in GetImageFromString.
With the using statement you are disposing the image before the UI thread can display the image properly. Take the code out of the using block and add a Dispose() statement to the Form.Close() method.

Imagestream to file resulting in partially gray image (sometimes)

I having an issue uploading / sending images from a stream to a generic handler in ASP.NET. I’ve build a windows phone app that can take an image and send it to the generic handler on my website.
Unfortunately in some occasions the image turns out to be (partially) gray. I think it might have something to to with a lost/bad internet connection of the mobile device. This problem happens every 50 images or so.
When the faulty image is send I do not get an error of any kind. I’m looking for two possible solutions.
How do i prevent the windows phone uploading a partially gray image to the generic handler.
How do i check if an image is partially gray on the server so can send a error message back to the phone.
to make this question more compleet I included the code of the generic handler and an example image. Second I’m very curious why this occus. TCPIP has an handshake so above isseu should not be possible ?
public class UploadImages : IHttpHandler
{
private IWorkOrderRepository _workOrderRepository;
private IDigitalFileRepository _digitalFileRepository;
private IUserRepository _userRepository;
public UploadImages()
{
_workOrderRepository = ((Global)HttpContext.Current.ApplicationInstance).Kernel.Get<IWorkOrderRepository>();
_digitalFileRepository = ((Global)HttpContext.Current.ApplicationInstance).Kernel.Get<IDigitalFileRepository>();
_userRepository = ((Global)HttpContext.Current.ApplicationInstance).Kernel.Get<IUserRepository>();
}
public void ProcessRequest(HttpContext context)
{
var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
var user = (Domain.Users.User)HttpContext.Current.User;
string WorkOrderId = context.Request.QueryString["workOrderId"];
string latitude = context.Request.QueryString["LATITUDE"];
string Longitude = context.Request.QueryString["LONGITUDE"];
if (latitude != "0" && Longitude != "0")
{
string file = "Filename.jpg";
string uploadPath = context.Server.MapPath("~/Temp/");
using (var stream = new MemoryStream())
{
var image = ImageResizer.Resize(Image.FromStream(context.Request.InputStream), 700);
image.Save(stream, ImageFormat.Jpeg);
stream.Position = 0;
var workOrder = _workOrderRepository.GetAll(x => x.Id == Convert.ToInt32(WorkOrderId)).FirstOrDefault();
workOrder.AddPhoto(_workOrderRepository, _digitalFileRepository, new AuditInfo((Domain.Users.User)user), stream, file, "image/jpeg", Convert.ToDouble(latitude), Convert.ToDouble(Longitude));
}
}
else
{
string file = "Filename.jpg";
string uploadPath = context.Server.MapPath("~/Temp/");
using (var stream = new MemoryStream())
{
var image = ImageResizer.Resize(Image.FromStream(context.Request.InputStream), 700);
image.Save(stream, ImageFormat.Jpeg);
stream.Position = 0;
var workOrder = _workOrderRepository.GetAll(x => x.Id == Convert.ToInt32(WorkOrderId)).FirstOrDefault();
workOrder.AddPhoto(_workOrderRepository, _digitalFileRepository, new AuditInfo((Domain.Users.User)user), stream, file, "image/jpeg");
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}

Categories