I'm getting images from a url:
BitmapImage image = new BitmapImage(new Uri(article.ImageURL));
NLBI.Thumbnail.Source = image;
This works perfect, now i need to put it in a stream, to make it into byte array. I'm doing this:
WriteableBitmap wb = new WriteableBitmap(image);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
And code fails with NullReference, how to fix it?
var webClient = new WebClient();
byte[] imageBytes = webClient.DownloadData(article.ImageURL);
You get a NullReference exception because the image is still not loaded when you use it. You can wait to the ImageOpened event, and then work with it:
var image = new BitmapImage(new Uri(article.ImageURL));
image.ImageOpened += (s, e) =>
{
image.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap wb = new WriteableBitmap(image);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
};
NLBI.Thumbnail.Source = image;
Other option is to get the stream of the image file directly using WebClient:
WebClient client = new WebClient();
client.OpenReadCompleted += (s, e) =>
{
byte[] imageBytes = new byte[e.Result.Length];
e.Result.Read(imageBytes, 0, imageBytes.Length);
// Now you can use the returned stream to set the image source too
var image = new BitmapImage();
image.SetSource(e.Result);
NLBI.Thumbnail.Source = image;
};
client.OpenReadAsync(new Uri(article.ImageURL));
you can use this:
private async Task<byte[]> GetImageAsByteArray(string urlImage, string urlBase)
{
var client = new HttpClient();
client.BaseAddress = new Uri(urlBase);
var response = await client.GetAsync(urlImage);
return await response.Content.ReadAsByteArrayAsync();
}
Related
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'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);
}
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 need to convert the images(fetching from web service) into base64String to store them in the SQLite database.
EDIT: I use ImageOpened so that the image is loaded/downloaded before I convert them into base64String but ImageOpened doest run. How do I achieve this task ? I mean to convert array of images into base64.
this is my code:
public async void LoadData()
{
//get Json
string str = await Helper.getJSON();
//Deserialize json
MainClass apiData = JsonConvert.DeserializeObject<MainClass>(str);
//the problem loop
for (int i = 0; i < apiData.Categories.Count;i++ )
{
//apiData.Categoriesp[i].icon_image is the url of the image
BitmapImage image = new BitmapImage(new Uri(apiData.Categories[i].icon_image,UriKind.RelativeOrAbsolute));
//it never runs
image.ImageOpened += (s, e) =>
{
//code for conversion of image into memory stream
image.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap wb = new WriteableBitmap(image);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
//setting imageInSql property of the list (but it never runs)
apiData.Categories[i].imageInSql = base64String;
};
}
//Inserting into database
using(var db= new SQLiteConnection(App.dbPath)){
//geting null in imageinSql property.
db.InsertAll(apiData.Categories,typeof(Category));
}
}
Thanks in advance.
For me it looks like a you are setting CreateOptions property inside the event handler.
image.ImageOpened += (s, e) =>
{
//code for conversion of image into memory stream
image.CreateOptions = BitmapCreateOptions.None;
You should do this like-
image.CreateOptions = BitmapCreateOptions.None;
image.ImageOpened += (s, e) =>
{
Try below code.
public async void LoadData()
{
//get Json
string str = await Helper.getJSON();
//Deserialize json
MainClass apiData = JsonConvert.DeserializeObject<MainClass>(str);
//the problem loop
for (int i = 0; i < apiData.Categories.Count;i++ )
{
//apiData.Categoriesp[i].icon_image is the url of the image
BitmapImage image = new BitmapImage(new Uri(apiData.Categories[i].icon_image,UriKind.RelativeOrAbsolute));
image.CreateOptions = BitmapCreateOptions.None
//it never runs
image.ImageOpened += (s, e) =>
{
//code for conversion of image into memory stream
WriteableBitmap wb = new WriteableBitmap(image);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
//setting imageInSql property of the list (but it never runs)
apiData.Categories[i].imageInSql = base64String;
};
}
//Inserting into database
using(var db= new SQLiteConnection(App.dbPath)){
//geting null in imageinSql property.
db.InsertAll(apiData.Categories,typeof(Category));
}
}
I have one pictureBox and a button on form1 one. When the button is clicked, it should upload the file to the server. For now I am using the below method. First save the image locally and then upload to the server:
Bitmap bmp = new Bitmap(this.form1.pictureBox1.Width, this.form1.pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
Rectangle rect = this.form1.pictureBox1.RectangleToScreen(this.form1.pictureBox1.ClientRectangle);
g.CopyFromScreen(rect.Location, Point.Empty, this.form1.pictureBox1.Size);
g.Dispose();
bmp.Save("filename", ImageFormat.Jpeg);
And then uploading that file:
using (var f = System.IO.File.OpenRead(#"F:\filename.jpg"))
{
HttpClient client = new HttpClient();
var content = new StreamContent(f);
var mpcontent = new MultipartFormDataContent();
content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
mpcontent.Add(content);
client.PostAsync("http://domain.com/upload.php", mpcontent);
}
I can't use the Bitmap type in StreamContent. How can I stream the image from pictureBox directly instead saving it as file first?
I came up with the below code using MemoryStream, but the uploaded file size is 0 using this method. Why?
byte[] data;
using (MemoryStream m = new MemoryStream())
{
bmp.Save(m, ImageFormat.Png);
m.ToArray();
data = new byte[m.Length];
m.Write(data, 0, data.Length);
HttpClient client = new HttpClient();
var content = new StreamContent(m);
var mpcontent = new MultipartFormDataContent();
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
mpcontent.Add(content, "file", filename + ".png");
HttpResponseMessage response = await client.PostAsync("http://domain.com/upload.php", mpcontent);
//response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync();
MessageBox.Show(body);
}
I am not sure if it is the correct way to do it, but I have solved it by creating a new stream and then copying the older one to it:
using (MemoryStream m = new MemoryStream())
{
m.Position = 0;
bmp.Save(m, ImageFormat.Png);
bmp.Dispose();
data = m.ToArray();
MemoryStream ms = new MemoryStream(data);
// Upload ms
}
Image returnImage = Image.FromStream(....);