When I Capture a Photo with the following code , I get the saved photo rotated 90 degree in Android and iOS
is there any solution for this issue? so I get the saved image orientation adjusted properly
FileResult photo = await MediaPicker.CapturePhotoAsync();
using Stream sourceStream = await photo.OpenReadAsync();
var picture = PlatformImage.FromStream(sourceStream);
string localFilePath = $"{FileSystem.CacheDirectory}/{photo.FileName}";
using FileStream localFileStream = File.OpenWrite(localFilePath);
await picture.SaveAsync(localFileStream, ImageFormat.Jpeg, quality: 0.90f);
Save the bytes of the source stream directly to the file stream.
Dont use an intermediate picture.
Related
Good day,
I have this code which upload an image to Google drive from file, everything works well:
// Create a new file on Google Drive
using (var fsSource = new FileStream(UploadFileName, FileMode.Open, FileAccess.Read))
{
// Create a new file, with metadata and stream.
var request = service.Files.Create(fileMetadata, fsSource, "image/jpg");
request.Fields = "*";
var results = await request.UploadAsync(CancellationToken.None);
}
Now I want to do some image manipulation before uploading so that I could convert the image to jpeg if the image is in another format (png or bmp for example) or resize the image, so I changed the file to stream for manipulation, I don't want to save it locally again because the code could be used on a website on mobiles, that's why I am saving to stream.
using (MemoryStream ms = new MemoryStream())
{
Image img = Image.FromFile(uploadfileName);
img.Save(ms, ImageFormat.Jpeg);
}
How can I now upload this ms stream to Google Drive?
Thanks for any clue, I'm not an expect in field.
Thanks all for assistance.
The answer suggested by canton7 works:
Just set ms.Position = 0, so that the next read starts reading from the beginning of the stream, then use it in place of your fsSource in your first snippet
using (var memoryStream = new MemoryStream())
{
await image.CopyToAsync(memoryStream);
using (var img = System.Drawing.Image.FromStream(memoryStream))
{
var bytesImage = Utilities.ImageToByteArray(img, ImageFormat.Jpeg);
using (MemoryStream memstr = new MemoryStream(bytesImage))
{
await blob.UploadFromStreamAsync(memstr);
}
}
}
the code above is used to upload file to blob storage the image has transparent like this
after uploading, the result contain black background like this
Please follow #Franz Gleichmann Answer,
"Well, you converted your picture to Jpg - a format that does not support transparency. nothing you can do there, except pick another format"
My bitmap is too large for uploading to the printer. I am going to compress it to smaller size so that less data will be transmit over the printer. But I don't want reduce the length and width of the bitmap. I have done some research but all of them require a stream especially as following
bitmap.compress(Bitmap.Format.jpeg,50,outputStream);
Why do I need a stream to store the file? How can I skip that and get the compressed bitmap that I want? I have tried
originalBitmap = Bitmap.decodeByteArray(imageByteData);
//Line below not working and got error
compressedBitmap = Bitmap.compress(Bitmap.Format.jpeg,50,outputStream);
In the outputStream which is my Download folder, I did see the compressed image, but how can I access the compressed image again? Unfortunately, the compress method is not that straight forward. My question is how can I compress a bitmap and use the compressed bitmap in another action? Thank you.
You can compress it to an in-memory stream:
//Compress to a stream in memory
byte[] compressedData = null;
using(var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.Format.Jpeg, 50, stream);
compressedData = stream.ToArray();
}
//load compressed bitmap from memory
using(var stream = new MemoryStream(compressedData))
{
var compressedBitmap = BitmapFactory.DecodeStream(stream);
}
I'm working on a function that takes a photo and convert it to base64 string. But for some reason, and i tried looking this up, Convert.ToBase64String always rotate my image 90 degrees counter clockwise. I have tried looking this up but couldnt find anyone with similair issue. Here's the code
private async Task<string> GetPhotoBase64StringAsync(int compressionQuality = 50, PhotoSize photoSize = PhotoSize.Medium)
{
string filename = $"{DateTime.Now.ToString("MMddyyyy_Hmmtt")}.jpg";
var photo = await UtilityService.OpenCameraAsync(filename, compressionQuality, photoSize);
if (photo != null)
{
var bytes = await photo.GetStream().ConvertToBytes();
var base64string = Convert.ToBase64String(bytes);
return base64string
}
return string.Empty;
}
photo is an object that is returned by the xamarin plugin that im using. I know for a fact that the plugin returns the image in the right orientation because i displayed afterward and its not rotated.
The problem happens when i convert the image to stream and from stream to base64. If i put a breakpoint at return base64string and copy and paste the base64 string to an online base64 to image convert, the image would come out rotated 90 degrees counter clockwise.
I have also tried
var base64string = bytes.ToBase64String(); but that didnt work either.
This is so strange and i have never countered this before.
Have you tried the good old IO.MemoryStream instead of .ConvertToBytes()?
byte[] bytes;
using (var memoryStream = new System.IO.MemoryStream())
{
photo.GetStream().CopyTo(memoryStream);
bytes = memoryStream.ToArray();
}
the problem was with the plugin. I'm using MediaPlugin and had to use the other getstream method
var bytes = await photo.GetStreamWithImageRotatedForExternalStorage().ConvertToBytes();
var base64string = Convert.ToBase64String(bytes);
return base64string
I am trying to develop a simple Windows 8 Metro app which simply downloads an image file from a given URL (say http://sample.com/foo.jpg) and then save it to Pictures Library.
I have an image control in the UI to display the downloaded image.
I'm also facing difficulty in setting the image source for the image control to the newly downloaded image (actually I'm not even able to download it).
Also, is it possible to store the image file in a particular folder in the Pictures library (if it doesn't exist, then the app should create it)?
I'm really stuck here.
Please help me.
Here's some rough code that I believe accomplishes what you want. It assumes you have two image controls (Image1 and Image2) and that you have the Pictures Library capability checked in the manifest. Take a look at the XAML images sample as well
Uri uri = new Uri("http://www.picsimages.net/photo/lebron-james/lebron-james_1312647633.jpg");
var fileName = Guid.NewGuid().ToString() + ".jpg";
// download pic
var bitmapImage = new BitmapImage();
var httpClient = new HttpClient();
var httpResponse = await httpClient.GetAsync(uri);
byte[] b = await httpResponse.Content.ReadAsByteArrayAsync();
// create a new in memory stream and datawriter
using (var stream = new InMemoryRandomAccessStream())
{
using (DataWriter dw = new DataWriter(stream))
{
// write the raw bytes and store
dw.WriteBytes(b);
await dw.StoreAsync();
// set the image source
stream.Seek(0);
bitmapImage.SetSource(stream);
// set image in first control
Image1.Source = bitmapImage;
// write to pictures library
var storageFile = await KnownFolders.PicturesLibrary.CreateFileAsync(
fileName,
CreationCollisionOption.ReplaceExisting);
using (var storageStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(stream.GetInputStreamAt(0), storageStream.GetOutputStreamAt(0));
}
}
}
// read from pictures library
var pictureFile = await KnownFolders.PicturesLibrary.GetFileAsync(fileName);
using ( var pictureStream = await pictureFile.OpenAsync(FileAccessMode.Read) )
{
bitmapImage.SetSource(pictureStream);
}
Image2.Source = bitmapImage;
}