Cannot get Uri for an in-memory object because of missing PackageStore class - c#

I need to get the URI of an in-memory bitmap because the class I want to use accepts only bitmap URIs, not byte[] data. Also, I don't want to create temporary files for this purpose but operate only with the memory. In .NET Framework I can do this:
Uri GetMemoryBitmapUri()
{
MemoryStream packStream = new MemoryStream();
Package pack = Package.Open(packStream, FileMode.Create, FileAccess.ReadWrite);
Uri packUri = new Uri("packUri:");
PackageStore.AddPackage(packUri, pack); // we don't have PackageStore in .NET
Uri packPartUri = new Uri("/bitmap.jpg", UriKind.Relative);
PackagePart packPart = pack.CreatePart(packPartUri, System.Net.Mime.MediaTypeNames.Image.Jpeg);
var bitmapBytes = GetInMemoryBitmapData();
packPart.GetStream().Write(bitmapBytes, 0, bitmapBytes.Length);
return PackUriHelper.Create(packUri, packPart.Uri);
}
And it works - the reference returned from GetMemoryBitmapUri() can be passed to the method of the class I would like to use and the bitmap is drawn.
But I have a problem when trying to do this in .NET 7 since there is no longer PackageStore class in System.IO.Packaging and so I cannot make PackageStore.AddPackage call. How can I handle this problem?

Related

ByteArray to IFormFile

I am developing some REST API with C# and Net Core
I have a function in my repository which accepts a parameter of type IFormFile.
public async Task<bool> UploadFile(IFormFile file)
{
// do some stuff and save the file to azure storage
}
This function is called by a controller method which pass it the uploaded file
public class FileController : Controller
{
public async Task<IActionResult> UploadDoc(IFormFile file
{
// Call the repository function to save the file on azure
var res = await documentRepository.UploadFile(file);
}
}
Now I have another function that calls an external API which returns a file as a byte array. I'd like to save this byte array using the repository.UploadFile method but I can't cast the byte array object to IFormFile.
Is it possible?
You can convert the byte array to a MemoryStream:
var stream = new MemoryStream(byteArray);
..and then pass that to the constructor of the FromFile class:
IFormFile file = new FormFile(stream, 0, byteArray.Length, "name", "fileName");
Your repo shouldn't be using IFormFile. That's an abstraction that only applies to one particular method of HTTP file transfer (namely a multipart/form-data encoded request body). Something like your repo should have no knowledge of the source of the file (HTTP), nor how it was transmitted (multipart/form-data vs application/json for example).
Instead, you should use Stream for your param. In your UploadDoc action, then, you can simply do:
using (var stream = file.OpenReadStream())
{
await documentRepository.UploadFile(stream);
}
And, where you have just a byte array:
using (var stream = new MemoryStream(byteArray))
{
await documentRepository.UploadFile(stream);
}
You might also consider adding an overload of UploadFile that takes a byte[], as creating a new memory stream from a byte array just to have a stream is a waste of resources. However, a byte[] has to be handled differently than a Stream, so it may require some duplication of logic to go that route. You'll need to evaluate the tradeoffs.
Create a new MemoryStream based on the byte array.
Create a new FormFile object based on the MemoryStream.
Make sure to append the ContentDisposition header, otherwise you will be unable to operate your FormFile object as a C# exception will be thrown.
The complete code:
using (var stream = new MemoryStream(byteArray))
{
var file = new FormFile(stream, 0, byteArray.Length, name, fileName)
{
Headers = new HeaderDictionary(),
ContentType = contentType,
};
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = file.FileName
};
file.ContentDisposition = cd.ToString();
}

Sending Image from C# to Android via JSON

I have images stored in SQL server, and I want to send them to Android app via JSON with other data. What's the best way to do this?
BTW my server side written in ASP Web API(C#).
In other way I want to make my image like this http://myserver/image.jpg
so I can included in my JSON and download it in Android app.
As its not where clear from your question, This Link is the best what I can find for you. In it he is accessing ASP.NET WebAPI and converting all the things to JSON when access or pass it through the Andriod studio
http://hintdesk.com/how-to-call-asp-net-web-api-service-from-android/
and here is a complete series that can help you more
http://www.tutecentral.com/restful-api-for-android-part-1/
Hope this helps
I finally figure it out
This is the code
public HttpResponseMessage getImage(String name)
{
name = name + ".png";
var result = new HttpResponseMessage(HttpStatusCode.OK);
String filePath = HostingEnvironment.MapPath("~/images/"+name);
FileStream fileStream = new FileStream(filePath, FileMode.Open);
Image image = Image.FromStream(fileStream);
MemoryStream memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Jpeg);
result.Content = new ByteArrayContent(memoryStream.ToArray());
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
fileStream.Dispose();
return result;
}

UnauthorizedAccessException using AsRandomAccessStream

I just upgraded my project from Win 8 to Win 8.1 and I'm trying to take advantage of some of the new features in the SDK. One of those is the new AsRandomAccessStream extension method. The problem I'm having is when I use it, I'm getting an Unauthorized Access Exception.
Exception:Caught: "MemoryStream's internal buffer cannot be accessed."
(System.UnauthorizedAccessException) A
System.UnauthorizedAccessException was caught: "MemoryStream's
internal buffer cannot be accessed." Time: 3/11/2014 10:23:11 AM
Thread:[4308]
BitmapImage image = new BitmapImage();
var imageStream = new MemoryStream(imageBytes as byte[]);
image.SetSource(imageStream.AsRandomAccessStream());
imageBytes is a valid byte[]
imageStream is a valid MemoryStream
imageStream.Position = 0
any thoughts?
I encountered this problem today and to me, it appears as an API bug/inconsistency.
In .NET 4, calls to MemoryStream.GetBuffer() require the usage of certain constructors (see https://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer.aspx). More specifically, the buffer of the MemoryStream must be marked as exposable.
Now, AsRandomAccessStream() calls MemoryStream.GetBuffer(). However, in Win8.1, the constructor for setting the expose-ability of a MemoryStream is missing. Therefore, when you create the MemoryStream, use the default empty constructor and then call Write().
Thus, I think this should work.
BitmapImage image = new BitmapImage();
var imageStream = new MemoryStream();
imageStream.Write(yourdata, 0, yourdata.Length);
image.SetSource(imageStream.AsRandomAccessStream());
A simple workaround is to combine some extension methods.
var image = new BitmapImage();
var imageSource = imageBytes.AsBuffer().AsStream().AsRandomAccessStream();
image.SetSource(imageSource);

Unable to pass MemoryStream parameter to WCF method?

I have a method in Service1.svc.cs, below is the code
public void SaveData(int UserId, System.IO.MemoryStream File)
{
//Some code
}
I am passing values from xaml.cs
savedata.SaveDataAsync(userId, ms);
The error is
cannot convert from 'System.IO.MemoryStream' to
'SignSilverlight.ServiceReference1.MemoryStream'
How to solve ?
Memory stream is a .NET local object and it is not possible to pass it to a remote machine that might not even run .NET.
You have to pass a byte[] array instead. But be aware of size limits in endpoint's settings.
Here is how to (de)serialize a memory stream to array
// first endpoint
var streamSending = new MemoryStream();
var array = streamSending.ToArray();
// second endpoint
var streamRecieving = new MemoryStream(array);

Metro APP - BitmapImage to Byte[] or Download Image from Web and convert it to a Byte[] Array

Is there a way to convert a BitmapImage (Windows.UI.Xaml.Media.BitmapImage) to an Byte[] Array? Nothing I've tried work....
Another possible scenario (if BitmapImage cannot be converted to Byte array) is to download the image from web and then convert it to an array...
But I don't know how I can do that...
It would be really nice, if someone have an idea.
Current try:
HttpClient http = new HttpClient();
Stream resp = await http.GetStreamAsync("http://localhost/img/test.jpg");
var ras = new InMemoryRandomAccessStream();
await resp.CopyToAsync(ras.AsStreamForWrite());
BitmapImage bi = new BitmapImage();
bi.SetSource(ras);
byte[] pixeBuffer = null;
using (MemoryStream ms = new MemoryStream())
{
int i = bi.PixelHeight;
int i2 = bi.PixelWidth;
WriteableBitmap wb = new WriteableBitmap(bi.PixelWidth, bi.PixelHeight);
Stream s1 = wb.PixelBuffer.AsStream();
s1.CopyTo(ms);
pixeBuffer = ms.ToArray();
}
But it doesn't work... i & i2 are always set to 0. So ras doesn't work correctly.... What's going on?
Thanks
In your code you're never waiting for the BitmapImage to load the image from the web, so it does not know its PixelWidth/PixelHeight when you access them. You could wait for it to load - for example using the AsyncUI library by calling "await bi.WaitForLoadedAsync()". This would not really help you here if you want to access the decoded pixels since BitmapImage does not give you access to the pixels and there is currently no API to convert a BitmapImage into a WriteableBitmap.
You can check an earlier question about the topic. You would need to get the image file from the web with something like HttpClient.GetAsync(), then load it using something like BitmapDecoder.

Categories