I'm not trying to read the EXIF data on either the device or server, but the data needs to be present on the server.
I am currently sending the image to the server via converting it to a byte[] and then to base64 Convert.ToBase64(byte[]) and sending it using JSON - see code below.
But when I get the file at the other end, it doesn't have any EXIF data. If I get the image off the emulator with the fake SD card, the EXIF data exists.
Does anyone know how to upload the image and then reconstruct it at the other end so that the EXIF data stays intact?
Image to bytes to base64 to JSON
BitmapImage image = new BitmapImage();
image.SetSource(e.ChosenPhoto);
image = ResizeImage(image);
byte[] imageBytes;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(image);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, image.PixelWidth, Image.PixelHeight, 0, 100);
image = null;
imageBytes = ms.ToArray();
}
Base64Image imagestring = new Base64Image();
imagestring.imagestring = Convert.ToBase64String(imageBytes);
string json = JsonConvert.SerializeObject(imagestring);
JSON To base64 to byte[] to image
using (StreamReader sr = new StreamReader(inputStream))
{
postData = sr.ReadToEnd();
}
JavaScriptSerializer deserializer = new JavaScriptSerializer();
Dictionary<string, object> jsonObjects = (Dictionary<string, object>)deserializer.DeserializeObject(postData);
string base64image = jsonObjects["imagestring"].ToString();
byte[] imagebytes = Convert.FromBase64String(base64image);
BitmapImage bitmapImage = new BitmapImage();
MemoryStream ms = new MemoryStream(imagebytes);
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnDemand;
bitmapImage.CreateOptions = BitmapCreateOptions.None;
bitmapImage.Rotation = Rotation.Rotate0;
bitmapImage.StreamSource = ms;
bitmapImage.EndInit();
bitmapImage.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap wBmp = new WriteableBitmap(bitmapImage);
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wBmp));
I had to change my code completely to cut out any connection to Bitmaps or other formats, and just used byte[] through it. See code:
On the app:
ImageData imagedata = new ImageData();
byte[] imagebytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(imagebytes, 0, int.Parse(e.ChosenPhoto.Length.ToString()));
imagedata.imagestring = Convert.ToBase64String(imagebytes);
string json = JsonConvert.SerializeObject(imagedata);
At the server:
JavaScriptSerializer deserializer = new JavaScriptSerializer();
deserializer.MaxJsonLength = 50000000;
Dictionary<string, object> jsonObjects = (Dictionary<string, object>)deserializer.DeserializeObject(postData);
string base64image = jsonObjects["imagestring"].ToString();
byte[] imagebytes = Convert.FromBase64String(base64image);
Guid imagename = Guid.NewGuid();
if (!Directory.Exists(EM.ImagePath))
Directory.CreateDirectory(EM.ImagePath);
using (FileStream sw = new FileStream(EM.ImagePath + imagename + ".jpg", FileMode.CreateNew))
{
sw.Write(imagebytes, 0, imagebytes.Length);
}
Related
in my app I'm uploading images to server. I encode image from my WP 8.1 and send it to server. Sending and receiving work well but I have problem with image. I don't know why but whem I uploaded the image photographed on portrait after decoding is this image rotated by 90 degrees. Landscapes images are good, but portrait are rotated. Here is my encode and decode code
Encode:
private async Task<string> StorageFileToBase64(StorageFile file)
{
string Base64String = "";
if (file != null)
{
IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);
var reader = new DataReader(fileStream.GetInputStreamAt(0));
await reader.LoadAsync((uint)fileStream.Size);
byte[] byteArray = new byte[fileStream.Size];
reader.ReadBytes(byteArray);
Base64String = Convert.ToBase64String(byteArray);
}
return Base64String;
}
Decode image on server
public void ShowImg(string b64)
{
byte[] imageBytes = Convert.FromBase64String(b64);
// Convert byte[] to Image
var ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
f.pictureBox1.Image = image;
}
string startExpression = "data:image/png;base64,";
using (var ms = new MemoryStream())
{
ms.Flush();
System.Drawing.Image imageIn = System.Drawing.Image.FromFile(fileName);
ms.Position = 0;
imageIn.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipX);
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
var bytes= ms.ToArray();
string fileBase = Convert.ToBase64String(bytes);
var base64= startExpression + fileBase;
imageIn.Dispose();
ms.Dispose();
}
I write image in local database.
MemoryStream stream = new MemoryStream();
WriteableBitmap mywbq = new WriteableBitmap(bmp);
mywbq.SaveJpeg(stream, mywbq.PixelWidth, mywbq.PixelHeight, 0, 95);
byte[] imagearray = stream.ToArray();
stream.Close();
db._contacts.InsertOnSubmit(new MyContactsList {ItemImage = imagearray });
db.SubmitChanges();
And I want this picture display in xaml.
How it's impossible?
I use it source
But this class doesn't work
Simple as that:
byte[] yourImageBytesFromDatabase = ......;
MemoryStream ms = new MemoryStream();
ms.Write(yourImageBytesFromDatabase, 0, yourImageBytesFromDatabase.Length);
BitmapImage src = new BitmapImage();
src.SetSource(ms);
I've got WCF service to send image as a stream to client app.
My client app gets the stream :
Stream imageStream = client.GetImage();
When I use this code:
imageStream.CopyTo(stream);
int size = (int)stream.Length;
stream.Seek(0, SeekOrigin.Begin);
BitmapFrame bf = BitmapFrame.Create(stream,
BitmapCreateOptions.None,
BitmapCacheOption.OnLoad);
cam_img.Source = bf;
It work's fine but I need apply some filters to image before assign to source.
So I need bitmap. First, I convert Stream imageStream to byte array and then I use some code I find on forums:
byte[] tab_img;
using (var memoryStream = new MemoryStream())
{
imageStream.CopyTo(memoryStream);
tab_img= memoryStream.ToArray();
}
Bitmap bm;
using (MemoryStream mStream = new MemoryStream())
{
mStream.Write (tab_img, 0, tab_img.Length);
mStream.Seek(0, SeekOrigin.Begin);
bm = new Bitmap(mStream);
Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap bm_post = filter.Apply(bm);
ImageSourceConverter c = new ImageSourceConverter();
object source = new ImageSourceConverter().ConvertFrom(bm_post);
ImageSource is1 = (ImageSource)source;
cam_img.Source = is1;
}
but I still get NullReferenceException in line
object source = new ImageSourceConverter().ConvertFrom(bm_post);
I am using this code for upload photo:
MemoryStream photoStream = new MemoryStream();
e.ChosenPhoto.CopyTo(photoStream);
photoStream.Position = 0;
byte[] buf = photoStream.ToArray();
string str = Convert.ToBase64String(buf);
string fileBase64 = HttpUtility.UrlEncode(str);
// Send fileBase64 to server
The server then decode the base64 string and name it "test.jpt".
the problem is that paint doesn't open the image uploaded on my server.
Why ?
i think your base64 string is incorrect. I have written this code, here it is, it works:
BitmapImage a = new BitmapImage();
a.SetSource(e.ChosenPhoto);
WriteableBitmap wb = new WriteableBitmap(a);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, a.PixelWidth, a.PixelHeight, 0, 50); //50 is a quality of a photo
imageBytes = ms.ToArray();
base64 = System.Convert.ToBase64String(imageBytes);
i am trying to convert a bitmap to a base64 string.i can convert to from string to bitmap...but it seems like there is a problem when converting from bitmap to string.I was hoping you guys could give me a hand
public static string BitmapToString(BitmapImage image)
{
Stream stream = image.StreamSource ;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
return Convert.ToBase64String(buffer);
}
it gets a ArgumentNullException was unhandled
Value cannot be null.
Parameter name: inArray
when returning Convert.ToBase64String(buffer)
Help?
Try this alternative:
public string BitmapToBase64(BitmapImage bi)
{
MemoryStream ms = new MemoryStream();
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bi));
encoder.Save(ms);
byte[] bitmapdata = ms.ToArray();
return Convert.ToBase64String(bitmapdata);
}
In your solution, it is not necessary that StreamSource will always have value if it is loaded using a Uri.
First of all, it is necessary to save BitmapImage data into memory using some bitmap encoder (PngBitmapEncoder for example).
public static byte[] EncodeImage(BitmapImage bitmapImage)
{
using (MemoryStream memoryStream = new MemoryStream())
{
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
encoder.Save(memoryStream);
return memoryStream.ToArray();
}
}
Then just encode the binary data with Base64-encoding.
const string filePath = #"...";
const string outFilePath = #"...";
const string outBase64FilePath = #"...";
// Constuct test BitmapImage instance.
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = File.OpenRead(filePath);
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
// Convert BitmapImage to byte array.
byte[] imageData = EncodeImage(bitmapImage);
File.WriteAllBytes(outFilePath, imageData);
// Encode with Base64.
string base64String = Convert.ToBase64String(imageData);
// Write to file (for example).
File.WriteAllText(outBase64FilePath, base64String);