MemoryStream into MagicImage - c#

I am trying to store MemoryStream into MagicImage, but when I am trying to upload file with heic format it still uploading with heic format, but it should upload it with jpeg format. So I kind of do not understand where I am doing wrong. So could someone help me? I am trying it open in Frame in web, but it does not open bc it is not converting it to jpeg.
using (MemoryStream ms = new MemoryStream())
{
create.PostedFile.InputStream.CopyTo(ms);
var data = ms.ToArray();
byte[] data1 = null;
using (var image = new MagickImage(data))
{
// Sets the output format to jpeg
image.Format = MagickFormat.Jpeg;
// Create byte array that contains a jpeg file
data1 = image.ToByteArray();
}
var file = new ClientFile
{
Data = data1, // here where it should store it in jpeg
};

While I have never used your way of writing the image, this is what I use in my implementations and it always works:
var image = new MagickImage(sourceStream);
var format = MagickFormat.Jpg;
var stream = new MemoryStream();
image.Write(stream, format);
stream.Position = 0;
EDIT
If you don't add:
stream.Position = 0
sending the stream will not work as it will start saving from the current position which is at the end of the stream.

Related

How to save an Image to Clients System using .Net Core

I have an Image I am retrieving from the database as a byte array. I want to save it outside the Project i.e on the Clients System. I would appreciate if the code aspect can be assisted with. Here is a sample method I have so far:
public Image byteArrayToImage2()
{
var filePath = "C:\\cat.jpg";
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
Image returnImage = null;
using (MemoryStream ms = new MemoryStream(fileBytes))
{
returnImage = Image.FromStream(ms);
returnImage.Save("cat2.jpg", ImageFormat.Jpeg);
}
return returnImage;
}
Try the below approach
PS: make sure your fileBytes is of type byte Array.
MemoryStream imageStream = new MemoryStream();
imageStream.Write(fileBytes, 0, fileBytes.Length);
// Include the file name along with extension (Eg: 'C:\TestImage.JPEG')
FileStream fs = File.Create("Give the path where you want to save the image");
imageStream.WriteTo(fs);
fs.Close();
imageStream.Close();

Save a zip file to memory and unzip file from stream and get content

I am currently working on integrating Amazon Prime on our system and being stuck at getting the label back as ZPL format.
Basically, Amazon returns a base64 string, we will need to convert that string to a byte array, then save that array as a *.gzip file. From that gzip file, we can extract the content and get the zpl label content.
My question is, how we can do all of above without storing any temp files to system. I have researched some solutions but none is working for me.
My current code as below:
var str = "base64string";
var label = Convert.FromBase64String(str);
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
var demoFile = archive.CreateEntry("label.zip");
var entryStream = demoFile.Open();
using (var bw = new BinaryWriter(entryStream))
{
bw.Write(label);
}
var data = new MemoryStream();
using (var zip = ZipFile.Read(entryStream))
{
zip["label"].Extract(data);
}
data.Seek(0, SeekOrigin.Begin);
entryStream.Close();
}
using (var fileStream = new FileStream(#"D:\test.zip", FileMode.Create))
{
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(fileStream);
}
}
If I save the file as test.zip, I can successfully get the label back. But if I try to extract it directly to another stream, I get an error
A stream from ZipArchiveEntry has been disposed
I've done something similar, taking PNG label data from a zipped web response. This is how I went about that
using (WebClient webClient = new WebClient())
{
// Download. Expect this to be a zip file
byte[] data = webClient.DownloadData(urlString);
MemoryStream memoryStream = new MemoryStream(data);
ZipArchive zipArchive = new ZipArchive(memoryStream);
foreach (var zipEntry in zipArchive.Entries)
{
// Can check file name here and ignore anything in zip we're not expecting
if (!zipEntry.Name.EndsWith(".png")) continue;
// Open zip entry as stream
Stream extractedFile = zipEntry.Open();
// Convert stream to memory stream
MemoryStream extractedMemoryStream = new MemoryStream();
extractedFile.CopyTo(extractedMemoryStream);
// At this point the extractedMemoryStream is a sequence of bytes containing image data.
// In this test project I'm pushing that into a bitmap image, just to see something on screen, but could as easily be written to a file or passed for storage to sql or whatever.
BitmapDecoder decoder = PngBitmapDecoder.Create(extractedMemoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
BitmapFrame frame = decoder.Frames.First();
frame.Freeze();
this.LabelImage.Source = frame;
}
}
I was overthinking it. I finally found a simple way to do it. We just need to convert that base64 string to bytes array and use GzipStream to directly decompress it. I leave the solution here in case someone needs it. Thanks!
var label = Convert.FromBase64String(str);
using (var compressedStream = new MemoryStream(label))
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}

Best way to send images between an Universal Application and a web service

Hi i'm making an aplication that takes a picture from a car and its driver and this pictures are send to a web service, i am having problems for dealing with this situation, right now i've tried to send an encoded 64 base string, but this is not working
EDIT
Here is the code that i'm using for take the picture and save it as a byte array
ImageEncodingProperties format = ImageEncodingProperties.CreateJpeg();
//rotate and save the image
using (var imageStream = new InMemoryRandomAccessStream())
{
//generate stream from MediaCapture
await PhotoCapture.CapturePhotoToStreamAsync(format, imageStream);
await PhotoCapture.StopPreviewAsync();
//create decoder and encoder
BitmapDecoder dec = await BitmapDecoder.CreateAsync(imageStream);
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(imageStream, dec);
//roate the image
enc.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
//write changes to the image stream
await enc.FlushAsync();
PreviewImage = new WriteableBitmap(350, 500);
PreviewImage.SetSource(imageStream);
}
CaptureElement.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
using (var ms = PreviewImage.PixelBuffer.AsStream())
{
MemoryStream memoryStream = new MemoryStream();
ms.CopyTo(memoryStream);
DriverModel.Picture = memoryStream.ToArray();
}
When i'm doing this the array size is like 28 millions, obviusly i'm making something wrong

Convert ImageSource to Base64String - WP8

am working on WP8application, I have few images in location Resources\Graphics\ i am trying to display images from these folder, but its not picking the path.
Here is my code :
<img src=\"/Resources;component/Graphics/"+ImageName).Append("\" ") this is in my string which i am using in my WebBrowserControl.
WebBrowserControl.NavigateToString(html); // here html is a string which has all the html code in it.
But its not display the images.
So i want to convert the ImageSource --Resources;component/Graphics/"+ImageName to Base64String how to do it?
I have looked into many examples but none of them is compatible for WP8.
You can get StreamInfo by using this:
Application.GetResourceStream(new Uri("Resources;component/Graphics/"+ImageName", System.UriKind.Relative));
Then you can read this stream into an byte array. After that, use Convert.ToBase64String() to get what you want. Try this. Maybe you can read the MSDN document to find how to use Stream.
var img = Application.GetResourceStream(new Uri("Resources;component/Graphics/"+ImageName", System.UriKind.Relative));
var buffer = new byte[img.Stream.Length];
img.Stream.Seek(0, SeekOrigin.Begin);
img.Stream.Read(buffer, 0, buffer.Length);
var base64 = Convert.ToBase64String(buffer);
It's very simple - load your image into a byte array and call
System.Convert.ToBase64String(imageArray).
That being said, this will not result in displaying the image. The NavigateToString requires html. See documentation
This is my code
byte[] bytearray = null;
using (var ms = new MemoryStream())
{
if (bmp != null)
{
var wbitmp = new WriteableBitmap(bmp);
wbitmp.SaveJpeg(ms, 46, 38, 0, 100);
bytearray = ms.ToArray();
}
}
if (bytearray != null)
{
// image base64 here
string btmStr = Convert.ToBase64String(bytearray);
}

Parameter is not valid when Reading an image from S3

I am getting parameter is not valid error when trying to convert stream to image.
I my C# ASP.NET application, I upload an image to Amazon S3 and download it again for manipulation.
I've checked that the uploaded image is ok by viewing it online on S3.
I am downloading the image using this code:
using (AmazonS3 client = new AmazonS3Client(accessKey, secretKey))
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = "mybucket",
Key = "temp/" + sp.FileGuid + Path.GetExtension(sp.FileName)
};
using (GetObjectResponse response = client.GetObject(request)) // S3Response
{
using (MemoryStream memStream = new MemoryStream())
{
int file_size_in_bytes = Convert.ToInt32(response.Headers.GetValues("Content-Length")[0]);
byte[] buffer = new Byte[file_size_in_bytes];
int numBytesToRead = file_size_in_bytes;
int read;
while ((read = response.ResponseStream.Read(buffer, 0, buffer.Length)) > 0)
{
memStream.Write(buffer, 0, read);
}
response.ResponseStream.Close();
...
I convert the response stream of the image to byte array in order to pass it to WCF service for later manipulation.
In the WCF I do (partial code):
using (Stream filestream = new MemoryStream(sp.ImageFile)
{
**// GET THE ERROR IN THIS LINE!**
System.Drawing.Image image = System.Drawing.Image.FromStream(filestream);
}
sp.ImageFile holds the convert response stream to byte array.
I read the byte array into a stream and create the image again from the stream. In the code above you can see where I get the parameter is not valid error.
I assume that in some place the conversion of the stream data of the image to either byte array or stream masses up the image data, so it created a corrupted image data, but I am not sure.
Spend all day trying to solve this without success. The only way it worked is when I directly pass the uploaded file stream to the System.Drawing.FromStream, but that's not what I want to do.
Really Need your help.
It's possible this may help. If the stream is not positioned at the begining the image may not load.
using (Stream filestream = new MemoryStream(sp.ImageFile)
{
var checkSeek = filestream.Seek(0, SeekOrigin.Begin);
**// GET THE ERROR IN THIS LINE!**
System.Drawing.Image image = System.Drawing.Image.FromStream(filestream);
}

Categories