I'm displaying an image from a base 64 string that came from an API. The problem is, the image is not being displayed.
Here's the code:
profilePictureImg.Source = GetUserImage(user.MobileNumber);
private BitmapImage GetUserImage(string phoneNumber)
{
BitmapImage bitmapImage = new BitmapImage();
var baseAddress = "http://192.168.0.103/vchatapi/api/Images/" + phoneNumber;
var http = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new System.Uri(baseAddress));
http.Accept = "application/json";
http.ContentType = "application/json";
http.Method = "GET";
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
var y ="";
var x = y.FromJson(content);
byte[] binaryData = Convert.FromBase64String(x);
using (MemoryStream ms = new MemoryStream(binaryData, 0, binaryData.Length))
{
ms.Write(binaryData, 0, binaryData.Length);
bitmapImage.StreamSource = ms;
}
return bitmapImage;
}
Any Ideas?? Thanks!
EDIT:
Got the fix. For some reason, it requires to call BeginInit and EndInit.
The image may be decoded as shown in this answer:
var binaryData = Convert.FromBase64String(x);
var bitmapImage = new BitmapImage();
using (var stream = new MemoryStream(binaryData))
{
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
}
The reason why you have to use BeginInit and EndInit is explained in the Remarks section of the BitmapImage MSDN documentation:
BitmapImage implements the ISupportInitialize interface to optimize
initialization on multiple properties. Property changes can only occur
during object initialization. Call BeginInit to signal that
initialization has begun and EndInit to signal that initialization has
completed. After initialization, property changes are ignored.
This may be one of those cases where it pays not to dispose the stream too eagerly; also, the Write here is unnecessary: you already added the data via the constructor. So just:
bitmapImage.StreamSource = new MemoryStream(binaryData);
return bitmapImage;
does that work?
You can try the following
byte[] binaryData = Convert.FromBase64String(x);
using (MemoryStream ms = new MemoryStream(binaryData))
{
bitmapImage = (Bitmap)Image.FromStream(ms);
}
Related
This is my URL
http://nry.hr2eazy.com//Modules//UserManagement//ImageLoader.ashx?PortalSettingId=1
I am using this code but the image not shown in PictureBox.
System.Net.WebRequest request =
System.Net.WebRequest.Create("http://daikin.hr2eazy.com//Modules/UserManagement/ImageLoader.ashx?PortalSettingId=1");
System.Net.WebResponse response = request.GetResponse();
System.IO.Stream responseStream =
response.GetResponseStream();
Bitmap bitmap2 = new Bitmap(responseStream);
pictureBox11.Image = bitmap2;
You could use the Load(string) method like:
myPictureBox.Load("https://i.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U");
Your url is returning as plain text, so there's a little more work to load it, but that should do it:
HttpClient client = new HttpClient();
var response = client.GetAsync("http://nry.hr2eazy.com//Modules//UserManagement//ImageLoader.ashx?PortalSettingId=1").Result;
var imageStream = response.Content.ReadAsStreamAsync().Result;
Bitmap img = new Bitmap(imageStream);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = img;
I am trying to update an image by setting the source property every second, this works however causes a flicker when updated.
CurrentAlbumArt = new BitmapImage();
CurrentAlbumArt.BeginInit();
CurrentAlbumArt.UriSource = new Uri((currentDevice as AUDIO).AlbumArt);
CurrentAlbumArt.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
CurrentAlbumArt.EndInit();
If I don't set IgnoreImageCache, the image does not update thus no flickering either.
Is there a way around this caveat?
Cheers.
The following code snippet downloads the whole image buffer before setting the Image's Source property to a new BitmapImage. This should eliminate any flicker.
var webClient = new WebClient();
var url = ((currentDevice as AUDIO).AlbumArt;
var bitmap = new BitmapImage();
using (var stream = new MemoryStream(webClient.DownloadData(url)))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}
image.Source = bitmap;
If the download takes some time, it would make sense to run it in a separate thread. You would then have to take care for proper cross-thread access by also calling Freeze on the BitmapImage and assigning Source in the Dispatcher.
var bitmap = new BitmapImage();
using (var stream = new MemoryStream(webClient.DownloadData(url)))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}
bitmap.Freeze();
image.Dispatcher.Invoke((Action)(() => image.Source = bitmap));
am using following code to download image from server but failed.
am using server authentication please help
private BitmapImage getimage (string uri)
{
var webRequest = WebRequest.Create(uri);//making a variable webrequest,
webRequest.Credentials = new NetworkCredential("user", "password");//credential is using for authentication
using (var webResponse = webRequest.GetResponse())//use for stucking problem of button
{
using (var responseStream = webResponse.GetResponseStream())
{
BitmapImage img = new BitmapImage();
img.BeginInit();
img.StreamSource = responseStream;
img.EndInit();
return img;
}
}
}
The problem is that you are closing the response stream before the image is completely downloaded. In order to ensure that it is completely downloaded, you can copy it to an intermediate MemoryStream. Moreover, you will have to set the BitmapCacheOption.OnLoad flag if you want to close the stream immediately after EndInit. See the Remarks section in BitmapImage.StreamSource .
using (var webResponse = webRequest.GetResponse())
using (var responseStream = webResponse.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
responseStream.CopyTo(memoryStream);
BitmapImage img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.StreamSource = memoryStream;
img.EndInit();
return img;
}
Alternatively you could delay the closing of the WebResponse until the image has been download completely. BitmapImage provides the DownloadCompleted and DownloadFailed event handlers for purposes like that. Note that closing the WebResponse also closes the response stream.
var webResponse = webRequest.GetResponse();
var img = new BitmapImage();
img.DownloadCompleted += (o, e) => webResponse.Close();
img.DownloadFailed += (o, e) => webResponse.Close();
img.BeginInit();
img.StreamSource = webResponse.GetResponseStream();
img.EndInit();
return img;
I am trying to upload an image to Amazon S3 but before that I am resizing the image. For resizing I have to pass the stream objects and at one point (line commented as //Error) I am getting 'Stream does not support writing.' Exception. Please help.
public ActionResult AddPost(AddPost post)
{
Guid guid = new Guid();
AccountController ac=new AccountController();
string randomId = guid.ToString();
PutAttributesRequest putAttributesAction = new PutAttributesRequest().WithDomainName("ThisIsMyEXDomainPosts").WithItemName(randomId);
List<ReplaceableAttribute> attrib = putAttributesAction.Attribute;
System.IO.Stream stream;
System.IO.StreamReader sr = new System.IO.StreamReader(post.imageFileAddress.ToString());
sr.ReadToEnd();
stream = sr.BaseStream;
Amazon.S3.Model.PutObjectRequest putObjectRequest = new Amazon.S3.Model.PutObjectRequest();
System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
System.Drawing.Image imgResized = ResizeImage(img, 640, 800);
System.IO.MemoryStream mstream = new System.IO.MemoryStream();
imgResized.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg);
mstream.WriteTo(stream);//Error
putObjectRequest.WithBucketName("TIMEXImages");
putObjectRequest.CannedACL = Amazon.S3.Model.S3CannedACL.PublicRead;
putObjectRequest.Key = randomId + "_0.jpg";
putObjectRequest.InputStream = stream;
Amazon.S3.Model.S3Response s3Response = as3c.PutObject(putObjectRequest);
s3Response.Dispose();
//Uploadig the Thumb
System.Drawing.Image imgThumb = ResizeImage(img, 80, 100);
imgThumb.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg);
mstream.WriteTo(stream);
putObjectRequest.WithBucketName("MyProjectImages");
putObjectRequest.CannedACL = Amazon.S3.Model.S3CannedACL.PublicRead;
putObjectRequest.Key = randomId + ".jpg";
putObjectRequest.InputStream = stream;
Amazon.S3.Model.S3Response s3Response2 = as3c.PutObject(putObjectRequest);
s3Response2.Dispose();
//Closing all opened streams
sr.Close();
stream.Close();
mstream.Close();
//Adding to SimpleDB
attrib.Add(new ReplaceableAttribute().WithName("category").WithValue(post.category));
attrib.Add(new ReplaceableAttribute().WithName("description").WithValue(post.description));
attrib.Add(new ReplaceableAttribute().WithName("favoriteCount").WithValue("0"));
attrib.Add(new ReplaceableAttribute().WithName("imageThug").WithValue(randomId));
attrib.Add(new ReplaceableAttribute().WithName("title").WithValue(post.title));
attrib.Add(new ReplaceableAttribute().WithName("userId").WithValue(ac.GetLoggedInUserId()));
sdb.PutAttributes(putAttributesAction);
return View();
}
It seems like the BaseStream of a StreamReader is read only - which makes sense. Why do you need to re-use this stream in the first place though? Just use the memory stream directly:
mstream.Position = 0;
putObjectRequest.InputStream = mstream;
Input stream doesnt support writing and vice versa is with Output stream. See if you have interchanged its meaning.
How can I get ImageSource from MemoryStream in WPF using c# ? or convert MemoryStream to ImageSource to display it as image in wpf ?
using (MemoryStream memoryStream = ...)
{
var imageSource = new BitmapImage();
imageSource.BeginInit();
imageSource.StreamSource = memoryStream;
imageSource.EndInit();
// Assign the Source property of your image
image.Source = imageSource;
}
Additional to #Darin Dimitrov answer if you disposed the stream before assigning to Image.Source nothing will show, so be careful
For example, the Next method will not work, From one of my projects using LiteDB
public async Task<BitmapImage> DownloadImage(string id)
{
using (var stream = new MemoryStream())
{
var f = _appDbManager.DataStorage.FindById(id);
f.CopyTo(stream);
var imageSource = new BitmapImage {CacheOption = BitmapCacheOption.OnLoad};
imageSource.BeginInit();
imageSource.StreamSource = stream;
imageSource.EndInit();
return imageSource;
}
}
you can not use returned imageSource from the last function
But this implementation will work
public async Task<BitmapImage> DownloadImage(string id)
{
// TODO: [Note] Bug due to memory leaks, if we used Using( var stream = new MemoryStream()), we will lost the stream, and nothing will shown
var stream = new MemoryStream();
var f = _appDbManager.DataStorage.FindById(id);
f.CopyTo(stream);
var imageSource = new BitmapImage {CacheOption = BitmapCacheOption.OnLoad};
imageSource.BeginInit();
imageSource.StreamSource = stream;
imageSource.EndInit();
return imageSource;
}