I'm trying to display an image on a Windows 8 app. The image data is gathered from a web service, and provided as a Base64 encoded string.
I found the following on Stack Overflow:
How do i read a base64 image in WPF?
However, when I come to use the BitmapImage Class, I can't seem to access System.Windows.Media.Imaging, even though the following Microsoft documentation leads us to believe that it is available for use in .NET 4.5, and with Windows 8 apps:
http://msdn.microsoft.com/en-us/library/ms619218.aspx
Many thanks for your help.
The classes you want are in the Windows.UI.Xaml.Media.Imaging namespace. Here is an example of taking a Base64 image and creating an image out of it ...
var img = #"/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQ ... "; // Full Base64 image as string here
var imgBytes = Convert.FromBase64String(img);
var ms = new InMemoryRandomAccessStream();
var dw = new Windows.Storage.Streams.DataWriter(ms);
dw.WriteBytes(imgBytes);
await dw.StoreAsync();
ms.Seek(0);
var bm = new BitmapImage();
bm.SetSource(ms);
// img1 is an Image Control in XAML
bm.ImageOpened += (s, e) => { this.img1.Source = bm; };
bm.ImageFailed += (s, e) => { Debug.WriteLine(e.ErrorMessage); };
I could not copy a full Base64 image into the answer.
Related
I've been searching for the past few days but did not manage to find a solution for my problem. I am currently working on a xamarin Android app. I want to display an image by using the byte array column from by database. I am using another program to find the byte array of a specific photo and after that I insert manually its value in the byte array column from my principal project.
This is my code where I am trying to reproduce the image:
Android.Graphics.Bitmap bitmap=BitmapFactory.DecodeByteArray(currentexercis.image, 0, currentexercis.image.Length);
viewHolder.exercis_photo.SetImageBitmap(bitmap);
Currentexercis.image represents the byte array from my database, and its value seems to be OK, however every time bitmap is null.
This is the code from my other program where I convert the image into bytearray:
Image img = Image.FromFile(opendlg.FileName);
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
dbpicEntities1 db = new dbpicEntities1();
db.MyPictures.Add(new MyPicture() { FileName=fileName, Data = ms.ToArray() });
db.SaveChanges();
MessageBox.Show("success");
I think you should use like this.
byte [] imageArray // is your data
MemoryStream mStream = new MemorySteram ();
mStream.write(imageArray,0,imageArray.Length);
Image img = Image.FromStream(mStream);
img.save(filelocation);
Bitmap bitmapimg = BitmapFactory.BitmapFactory.DecodeStream(mStream);
// if you want to use Bitmap
Byte Array to Image using C# in Xamarin
There are some third-party library which implements this feature quite well like Picasso or Glide.
For Glide, there is official document shows how to use it in Xamarin.Android project: Binding a .JAR.
Or you could directly use it from the nuget package:
Then you can code for example like this:
Glide.With(context)
.Load(imageBytes)
.Apply(RequestOptions.CircleCropTransform())
.Into(imageView);
convert to byteArray
byte[] imgdata = System.IO.File.ReadAllBytes(pathToImage);
convert byte array to bitmap
private void OnGetMemberAvatarCompleted(byte[] avatarBytes)
{
var avatarImageView = FindViewById<ImageView>(Resource.Id.memberProfile_avatar);
if (avatarImageView != null)
{
var imageBitmap = BitmapFactory.DecodeByteArray(avatarBytes, 0,avatarBytes.Length);
RunOnUiThread(() => avatarImageView.SetImageBitmap(imageBitmap));
}
}
Im writing my own cache for for our Silverlight application to get around any size problems.
The cache works fine, however, it doesnt work for images.
Ive narrowed down the problem to a little test application that converts a BitmapImage to bytes (to simulate reading it our from the cache) and then convert those bytes back into an image.
Here is the code:
public MainPage()
{
InitializeComponent();
firstImage.ImageOpened += first_Loaded;
}
void first_Loaded(object sender, RoutedEventArgs e)
{
var bmp = firstImage.Source;
var bytes = ToByteArray(bmp as BitmapImage);
otherImage.Source = CreateImageFromBytes(bytes);
}
private byte[] ToByteArray(BitmapImage bi)
{
var enc = new BitmapEncoder(bi);
return enc.GetBitmapData();
}
private BitmapImage CreateImageFromBytes(byte[] data)
{
var bitmapImage = new BitmapImage();
bitmapImage.ImageFailed += bitmapImage_ImageFailed;
var ms = new MemoryStream(data);
bitmapImage.SetSource(ms);
return bitmapImage;
}
void bitmapImage_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
Console.WriteLine(e.ErrorException.Message);
}
The ImageFailed event is always raised with the message "AG_E_NETWORK_ERROR"
Ive read a little about the problem and it seems to have to do with the origin of the image being different but surely I should be able to load an image from bytes in memory right?
Any ideas how to get around this?
I should add that the converting to bytes works fine since if I save those bytes down to disk I can open the image.
From the Remarks in the Silverlight BitmapImage page on MSDN:
The BitmapImage can be used to reference images in the JPEG and PNG
file formats.
Unfortunately the BitmapEncoder class that you are using seems to encode bitmaps in BMP format. Hence the encoded buffer can't be decoded by BitmapImage.
You would have to find another implementation of a BitmapEncoder, which is capable of encoding JPEG or PNG.
I'm staring with the Nokia Imaging SDK to play a little with it. Now, I'm facing the problem where I have an Image which already exists (in a folder in my visual studio solution) and I want to convert this image in order to use it in the BlendFilter class of the Nokia Imaging SDK. However I don't know how to use it.
I was trying to convert the existing image in a stream and then pass it as a parameter to the BlendFilter constructor. But not luck. The compiler says that the best overload method match ... has some invalid arguments.
This is the way I'm trying to load the existing image to a stream:
Image image = new Image();
image.Source = new BitmapImage(new Uri("/Images/Template3.2.png", UriKind.Relative));
BitmapImage bitImage = new BitmapImage(new Uri("/Images/Template3.2.png", UriKind.Relative));
WriteableBitmap Bitmap = new WriteableBitmap(bitImage);
And then:
var BlendFilter = new BlendFilter(bitImage, BlendFunction.Add); --> the compiler error is here
Does anyone know how to use the BlendFilter class? any example would be very helpful.
Regards!
Blend filter takes an IImageProvider as input. That means you can use any of the X-ImageSource classes as input and it will do all the work internally.
If you have a stream of the image I suggest you create an StreamImageSource and pass that to BlendFilter.
The list of different image sources is quite long, I suggest you look into the documentation and chose the one that is most appropriate to you.
Here is an example that takes a stream of an image as input, and blends a new image on top of it. For simplicity the other image is just an image filled with one color (ColorImageSource), but you can set any IImageProvider as source: chose the most convenient one.
using (var backgroundSource = new StreamImageSource(stream))
using (var filterEffect = new FilterEffect(backgroundSource))
{
using (BlendFilter blendFilter = new BlendFilter())
{
var size = new Windows.Foundation.Size(400, 400);
var color = Windows.UI.Color.FromArgb(250, 128, 255, 200);
blendFilter.ForegroundSource = new ColorImageSource(size, color);
blendFilter.BlendFunction = BlendFunction.Add;
filterEffect.Filters = new[] { blendFilter };
var result = await new JpegRenderer(filterEffect).RenderAsync();
}
}
I'm developing a control where user can set an image and i want this this to be as user friendly as possible - so support for copy & paste, drag & drop.
I've got this part working using IDataObjects, testing for fileformats of FileDrop, FileContents (eg from outlook), and bitmap eg:
private void GetImageFromIDataObject(IDataObject myIDO)
{
string[] dataformats = myIDO.GetFormats();
Boolean GotImage = false;
foreach (string df in dataformats)
{
if (df == DataFormats.FileDrop)
{
// code here
}
if (df == DataFormats.Bitmap)
{
// Source of my problem here... this gets & displays image but
// how do I then convert from here ?
ImageSource myIS = Utilities.MyImaging.ImageFromClipboardDib();
ImgPerson.Source = myIS;
}
}
}
The ImageFromClipboard code is Thomas Levesque's as referenced in the answer to this SO question wpf InteropBitmap to bitmap
http://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/
No matter how I get the image onto ImgPerson, this part is working fine; image displays nicely.
When user presses save I need to convert the image to a bytearray and send to a WCF server which will save to server - as in, reconstruct the bytearray into an image and save it in a folder.
For all formats of drag & drop, copy & paste the image is some form of System.Windows.Media.Imaging.BitmapImage.
Except for those involving the clipboard which using Thomas's code becomes System.Windows.Media.Imaging.BitmapFrameDecode.
If I avoid Thomas's code and use:
BitmapSource myBS = Clipboard.GetImage();
ImgPerson.Source = myBS;
I get a System.Windows.Interop.InteropBitmap.
I can't figure out how to work with these; to get them into a bytearray so I can pass to WCF for reconstruction and saving to folder.
Try this piece of code
public byte[] ImageToBytes(BitmapImage imgSource)
{
MemoryStream objMS = new MemoryStream();
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imgSource));
encoder.Save(objMS);
return objMS.GetBuffer();
}
You can also use JpegBitmapEncoder, BmpBitmapEncoder based on your requirements.
byte[] arr = ImageToBytes(ImgPerson.Source as BitmapImage);
I can't believe I didn't see this SO question but the this is essentially the same as my question:
WPF: System.Windows.Interop.InteropBitmap to System.Drawing.Bitmap
The answer being:
BitmapSource bmpSource = msg.ThumbnailSource as BitmapSource;
MemoryStream ms = new MemoryStream();
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmpSource));
encoder.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(ms);
So similar in execution to Nitesh's answer but crucially, works with an inter-op bitmap.
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;
}