I am trying to convert a base64string to Bitmapimage.
The below code is used in my windows phone project and it works fine, however I am reusing this code in my windows store app project and getting this error. I have no clue in fixing this error.
Error Msg:
The best overloaded method match for 'Windows.UI.Xaml.Media.Imaging.BitmapSource.SetSource(Windows.Storage.Streams.IRandomAccessStream)' has some invalid arguments
cannot convert from 'System.IO.MemoryStream' to 'Windows.Storage.Streams.IRandomAccessStream'
DATADB.cs
class DATADB
{
public class NewsObject
{
BitmapImage thumb = null;
public BitmapImage Thumb {
get {
if (thumb==null)
{
Regex rgx = new Regex("^[^,]*,");
thumb = Utilities.base64image(rgx.Replace(this.default_photo, ""));
}
return thumb;
}
}
public string date { get; set; }
public string id { get; set; }
public string info { get; set; }
}
}
Utilities.cs
class Utilities
{
public static BitmapImage base64image(string base64string)
{
if (base64string == "" || base64string == null) return null;
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes, 0, fileBytes.Length))
{
ms.Write(fileBytes, 0, fileBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms); //Getting error message here.
return bitmapImage;
}
}
}
Try using InMemoryRandomAccessStream instead of MemoryStream.
trying to use
bitmapImage.SetSource(new MemoryRandomAccessStream(ms));
instead of
bitmapImage.SetSource(ms);
Related
I have a class with a property of type System.Drawing.Image because I want to store images in it. When trying to scaffold a Web API controller with Entity Framework Core I get the error message:
Image of the error
I think the problem is that the System.Drawing.Image class has a "Tag" property of type object. Now, the question is how do I fix this mapping?
Option 1:
Instead of using System.Drawing.Image directly in EF mapping, you could map the data to another property of type byte[]
[NotMapped]
public System.Drawing.Image Image { get; set; }
public byte[] ImageData
{
get
{
using (var ms = new MemoryStream())
{
Image.Save(ms, Image.RawFormat);
return ms.ToArray();
}
}
set
{
if (value == null)
{
Image = null;
}
else
{
using (var ms = new MemoryStream(value))
{
Image = Image.FromStream(ms);
}
}
}
}
Option 2:
You could also leave only the ImageData property in the model and handle loading and saving the image outside the model.
public byte[] ImageData { get; set; }
I have a WebAPI 2.1 service (ASP.Net MVC 4) that receive and image and related data.
I need to send this image from WPF application, but I get 404 not found error.
Server side
[HttpPost]
[Route("api/StoreImage")]
public string StoreImage(string id, string tr, string image)
{
// Store image on server...
return "OK";
}
Client side
public bool SendData(decimal id, int time, byte[] image)
{
string url = "http://localhost:12345/api/StoreImage";
var wc = new WebClient();
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var parameters = new NameValueCollection()
{
{ "id", id.ToString() },
{ "tr", time.ToString() },
{ "image", Convert.ToBase64String(image) }
};
var res=wc.UploadValues(url, "POST", parameters);
return true;
}
The url exists, I thing I need to encode to json format, but I don't know how.
Thanks for your time!
The method parameters in your case are received in QueryString form.
I would suggest you turn the parameters list into one single object like this:
public class PhotoUploadRequest
{
public string id;
public string tr;
public string image;
}
Then in you API convert the string to buffer from Base64String like this:
var buffer = Convert.FromBase64String(request.image);
Then cast it to HttpPostedFileBase
HttpPostedFileBase objFile = (HttpPostedFileBase)new MemoryPostedFile(buffer);
Now you have the image file. Do whatever you want.
Full Code here:
[HttpPost]
[Route("api/StoreImage")]
public string StoreImage(PhotoUploadRequest request)
{
var buffer = Convert.FromBase64String(request.image);
HttpPostedFileBase objFile = (HttpPostedFileBase)new MemoryPostedFile(buffer);
//Do whatever you want with filename and its binaray data.
try
{
if (objFile != null && objFile.ContentLength > 0)
{
string path = "Set your desired path and file name";
objFile.SaveAs(path);
//Don't Forget to save path to DB
}
}
catch (Exception ex)
{
//HANDLE EXCEPTION
}
return "OK";
}
Edit:
I forgot to add the Code for MemoryPostedFile class
public class MemoryPostedFile : HttpPostedFileBase
{
private readonly byte[] fileBytes;
public MemoryPostedFile(byte[] fileBytes, string fileName = null)
{
this.fileBytes = fileBytes;
this.FileName = fileName;
this.InputStream = new MemoryStream(fileBytes);
}
public override void SaveAs(string filename)
{
File.WriteAllBytes(filename, fileBytes);
}
public override string ContentType => base.ContentType;
public override int ContentLength => fileBytes.Length;
public override string FileName { get; }
public override Stream InputStream { get; }
}
I have an application that takes photos, converts them into byte arrays and saves them locally in the Isolated Storage. It then reads them out and converts them back into an BitmapImage.
However, I can't seem to show the images in a ListBox. I am using the same code I have in another page that works perfectly.
The BitmapImage has a image in it, but that is as much as I know. Whether that image is legitimate or not, I don't know or know how to check.
Any ideas would be greatly appreciated.
SEE CODE BELOW
Convert Image
public byte[] ImageToBytes(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(img.PixelWidth, img.PixelHeight);
// write an image into the stream
Extensions.SaveJpeg(btmMap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
return ms.ToArray();
}
}
public BitmapImage BytesToImage(byte[] bytes)
{
BitmapImage bitmapImage = new BitmapImage();
MemoryStream ms = new MemoryStream(bytes);
bitmapImage.SetSource(ms);
return bitmapImage;
}
Class with image
public class NewItem
{
ObservableCollection<BitmapImage> images = new ObservableCollection<BitmapImage>();
[DataMember]
public ObservableCollection<BitmapImage> Images
{
get { return images; }
set { images = value; }
}
[DataMember]
public string Notes { get; set; }
[DataMember]
public string ItemID { get; set; }
}
Saving to storage
public static void AddOrUpdateUnsavedItems(NewItem _item)
{
var store = IsolatedStorageFile.GetUserStoreForApplication();
List<NewItem> allunsaveditems = new List<NewItem>();
if (store.FileExists("unsaveditem"))
{
allunsaveditems.Add(_item);
allunsaveditems.AddRange(LoadUnsavedItemsFromIsolatedStorage());
store.DeleteFile("unsaveditem");
}
UnsavedRegisters.Clear();
foreach (NewItem ni in allunsaveditems)
{
StoredItem newUnsavedItem = new StoredItem();
newUnsavedItem.ItemID = ni.ItemID;
newUnsavedItem.Notes = ni.Notes;
foreach (BitmapImage bmp in ni.Images)
{
newUnsavedItem.ImageBytes.Add(newUnsavedItem.ImageToBytes(bmp));
}
UnsavedRegisters.Add(newUnsavedItem);
}
using (var stream = new IsolatedStorageFileStream("unsaveditem", FileMode.OpenOrCreate, FileAccess.Write, store))
{
DataContractSerializer dcs = new DataContractSerializer(typeof(List<StoredItem>));
dcs.WriteObject(stream, UnsavedRegisters);
}
}
Loading from storage
public static List<NewItem> LoadUnsavedItemsFromIsolatedStorage()
{
List<NewItem> unsavedItems = new List<NewItem>();
try
{
var store = IsolatedStorageFile.GetUserStoreForApplication();
if (store.FileExists("unsaveditem"))
{
using (var stream = new IsolatedStorageFileStream("unsaveditem", FileMode.OpenOrCreate, FileAccess.Read, store))
{
if (stream.Length > 0)
{
DataContractSerializer dcs = new DataContractSerializer(typeof(List<StoredItem>));
List<StoredItem> storedItems = dcs.ReadObject(stream) as List<StoredItem>;
foreach (StoredItem si in storedItems)
{
NewItem ni = new NewItem();
ni.ItemID = si.ItemID;
ni.Notes = si.Notes;
foreach (byte[] imageBytes in si.ImageBytes)
{
ni.Images.Add(si.BytesToImage(imageBytes));
}
unsavedItems.Add(ni);
}
}
}
}
}
catch (Exception)
{
//MessageBox.Show("and error happened getting the unsaved items");
// handle exception
return null;
}
return unsavedItems;
}
This should not be a problem, I had this working for a BitmapSource, Which I believe BitmapImage inherits from, try the code below in your listbox
<Border Height="200" Width="200">
<Border.Background>
<ImageBrush ImageSource="{Binding ItemImage}" />
</Border.Background>
</Border>
ItemImage is the Property holding your BitmapSource image.
I don't know what has changed, but it started working.
Got a little bit of a problem. I have a program that builds an observable collection of Users. The User has a Firstname, Lastname, and Image. I can add the user to the observable collection, but I also want to save the collection and load it everytime I reopen the program.
My problem is that while its fairly easy to save a firstname and lastname, the writer can't write the image to the xml file. Is there any way around this?
Here's what I have so far:
the observable collection:
ObservableCollection<VendorClass> ProfileList = new ObservableCollection<VendorClass>();
the problematic writer:
XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<VendorClass>));
using (StreamWriter wr = new StreamWriter("vendors.xml")) //Data/customers.xml
{
xs.Serialize(wr, ProfileList);
}
Any ideas? And if there does exist a solution to write in an image, is there a viable way to read it out again?
XmlSerializer can't serialize or deserialize the WPF image types like BitmapImage etc. It is however able to (de)serialize byte arrays. So you may add a byte[] ImageBuffer property to your Person class, which contains the binary image data. You would then also set the XmlIgnore attribute on the Image property to suppress its (de)serialization, and set XmlElement("Image") on the ImageBuffer properties to (de)serialize it as <Image>...</Image>.
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
[XmlIgnore]
public BitmapSource Image { get; set; }
[XmlElement("Image")]
public byte[] ImageBuffer
{
get
{
byte[] imageBuffer = null;
if (Image != null)
{
using (var stream = new MemoryStream())
{
var encoder = new PngBitmapEncoder(); // or some other encoder
encoder.Frames.Add(BitmapFrame.Create(Image));
encoder.Save(stream);
imageBuffer = stream.ToArray();
}
}
return imageBuffer;
}
set
{
if (value == null)
{
Image = null;
}
else
{
using (var stream = new MemoryStream(value))
{
var decoder = BitmapDecoder.Create(stream,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
Image = decoder.Frames[0];
}
}
}
}
}
This approach has also been suggested for properties of type Bitmap in this answer.
You would base64 encode the image to convert it to a string and then write that into a CDATA section. See How do you serialize a string as CDATA using XmlSerializer?
In my app I have to download all the images from the remote server and display it in a list view .When i tried to extract the images from isolated storage I have got an exception
"Operation not permitted on IsolatedStorageFileStream"
.here is my code
public static object ExtractFromLocalStorage(Uri imageFileUri)
{
byte[] data;
string isolatedStoragePath = GetFileNameInIsolatedStorage(imageFileUri); //Load from local storage
if (null == _storage)
{
_storage = IsolatedStorageFile.GetUserStoreForApplication();
}
BitmapImage bi = new BitmapImage();
//HERE THE EXCEPTION OCCURS
using (IsolatedStorageFileStream sourceFile = _storage.OpenFile(isolatedStoragePath, FileMode.Open, FileAccess.Read))
{
data = new byte[sourceFile.Length];
// Read the entire file and then close it
sourceFile.Read(data, 0, data.Length);
// Create memory stream and bitmap
MemoryStream ms = new MemoryStream(data);
// Set bitmap source to memory stream
bi.SetSource(ms);
sourceFile.Close();
}
return bi;
}
the above function is used to get the bitmap image from isolated storage,and my model class is
public class Details
{
public string id { get; set; }
public string name { get; set; }
public Uri imgurl { get; set; }
[IgnoreDataMember]
public BitmapImage ThumbImage{get;set;}
}
and i am using a singlton class to call the function to get image.
public class SingleTon
{
static SingleTon instance = null;
private SingleTon()
{
}
public static SingleTon Instance()
{
if (instance == null)
{
instance = new SingleTon();
}
return instance;
}
public BitmapImage getImage(Uri uri)
{
lock (this)
{
BitmapImage image = new BitmapImage();
image = (BitmapImage)CacheImageFileConverter.ExtractFromLocalStorage(uri);
return image;
}
}
public void writeImageToIsolatedStorage(Uri imageUri)
{
lock (this)
{
CacheImageFileConverter.DownloadFromWeb(imageUri);
}
}
}
this is the code for set the image to the object
SingleTon singleton = SingleTon.Instance();
List<(Details > datalist = new Details()
foreach (Details items in DataList)
{
items.ThumbImage = singleton.getImage(items.imgurl );
datalist.add(items);
}
please any one help me with a solution.
This exception usually occurs if you haven't closed a previously open Stream to the same file. Check CacheImageFileConverter.DownloadFromWeb and make sure your output Stream is wrapped in a using block.
That exception might also be thrown if the file doesn't exist, but I'm not 100% sure. Maybe through in a call to IsolatedStorageFile.FileExists() before you open it just to be sure.