I am trying to implement a windows universal application. I am facing one issue for converting the image raw data(byte array) to the BitmapImage control. I don't know the type of the image raw data. I used the below code,
private async Task<BitmapImage> ByteArrayToBitmapImage(byte[] byteArray)
{
var bitmapImage = new BitmapImage();
var stream = new InMemoryRandomAccessStream();
await stream.WriteAsync(byteArray.AsBuffer());
stream.Seek(0);
bitmapImage.SetSource(stream);
return bitmapImage;
}
Image is not displayed in window. When I debugging , found that height & width of bitmapImage object is 0.
if anybody know the solution for this, please help me
Finally my issue solved , when I used the below code,
var bmp = new WriteableBitmap(320, 240);
using (var stream = bmp.PixelBuffer.AsStream())
{
stream.Write(bytes, 0, bytes.Length);
myImage.Source = bmp;
}
I'm using the same code and in works for me but I create BitmapImage and set its source on dispatcher's thread - maybe that's the key to your problem.
Related
I am sending DICOM images to my API by encoding as base64 from the frontend, which is in Angular CLI. Also, I have Rest API to get those encoded DICOM images and decode them back before had some process with them. But after decoding the DICOM image into the memory stream, metadata of DICOM images are lost. It is appreciatable if I got a better solution. Please find my codes below.
//Angular code
var file = event.dataTransfer ? event.dataTransfer.files[i] :
event.target.files[0];
//var pattern = /.dcm/;
var reader = new FileReader();
reader.onload = this._handleReaderLoaded.bind(this);
reader.readAsDataURL(file);
//Web API Code
[HttpPost("UploadFile/{Id}")]
public async Task<IActionResult> UploadFile(int Id, [FromBody] DICOMFiles
dicomfiles)
{
String base64Encoded = encodedImage;
string output =
encodedImage.Substring(encodedImage.IndexOf(',') + 1);
byte[] data = Convert.FromBase64String(output);
MemoryStream stream = new MemoryStream(data);
client.UploadFile(stream, "Projects/test_images/Test.dcm");
}
At last, I found a solution for this. The problem is not about decode from base64. The actual problem is with the client.UploadFile() method call.
Before using the client.uploadfile(), we need to make sure that the memory stream object is pointing to position "0". This will allow the client.UploadFile() method to create and write all the content of the mentioned file from the start of the byte[] array. we can do this as mentioned below.
stream.Position = 0;
I have an ellipse and I want to fill it with image. And I would like to set full path to the image to ImageSource property of ImageBrush. But I wasn't able to accomplish it.
I've tried to add:
C:/Users/someuser/Pictures/untitled.png
C:\\Users\\someuser\\Pictures\\untitled.png which came from FilePicker
C:\Users\misko\Pictures\untitled.png.
But non of this works. Can you please explain to me how to properly set full path?
You have to open the file first using FilePicker
if (file != null)
{
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
grid.Background = new ImageBrush
{
ImageSource = bitmapImage
};
}
I want to save an image to my Azure MobileService.
I have been looking around and found that you can use blob and azure storage. But instead of implementing this I would love if you could convert an image to string or stream that could be stored in a normal azure mobile service table.
I am creating images in my app as :
Canvas found = null;
try
{
found = FindParentOfType<Canvas>(ViewInteractionCanvas.canvas);
}
catch (Exception)
{
//MessageBox.Show(e.Message.ToString(), "ERROR", MessageBoxButton.OK);
found = ViewInteractionCanvas.canvas;
}
WriteableBitmap writeableBitmap = new WriteableBitmap(found, null);
var imageBrush = new ImageBrush
{
ImageSource = writeableBitmap,
Stretch = Stretch.None
};
writeableBitmap = null;
GC.Collect();
try
{
FindChildCanvas(found, imageBrush);
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString(), AppResources.ErrorSaving, MessageBoxButton.OK);
return false;
}
var fileStream = new MemoryStream();
writeableBitmap = new WriteableBitmap(found, null);
writeableBitmap.SaveJpeg(fileStream, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 100, 100);
fileStream.Seek(0, SeekOrigin.Begin);
string tempJPEG = "My.jpg";
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream IsofileStream = myIsolatedStorage.CreateFile(tempJPEG);
/*
StreamResourceInfo sri = null;
Uri uri = new Uri(tempJPEG, UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
*/
// Encode WriteableBitmap object to a JPEG stream.
//Extensions.SaveJpeg(wb, IsofileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
writeableBitmap.SaveJpeg(IsofileStream, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 100, 100);
IsofileStream.Close();
}
dialogResult = MessageBox.Show(AppResources.ShieldCreator_SaveShield, AppResources.ShieldCreator_SaveShieldTitle, MessageBoxButton.OKCancel);
if (dialogResult == MessageBoxResult.OK)
{
MediaLibrary library = new MediaLibrary();
library.SavePictureToCameraRoll("picture", fileStream);
}
if (dialogResult == MessageBoxResult.Cancel)
{
}
fileStream.Close();
I was thinking that I could send the filestream or something like that? But Have not succeeded in doing so. Maybe this is completely impossible. But just wanted to investigate the possibility instead of starting to learn a new concept.
Hope somebody can help.
By default, Mobile Services data is backed by SQL Database. As long as you can find a way to create a proper data type in your table, you'd be able to do this. Just keep in mind: SQL Database databases are limited to 150GB, which will be eaten up faster if storing content in the database instance vs, say, blob storage with a URL to that blob being stored in your SQL table (which also costs significantly less than SQL Database service).
What you're talking about doing (storing the image data in your SQL database) is possible and not altogether difficult, but definitely not recommended. There are several issues including the size of the data and the inefficiency of storing data like this. At the end of the day though, if that's how you want to implement it, I have posts explaining how you can do so from an Android and an iOS app.:
Android: http://chrisrisner.com/Storing-Images-from-Android-in-Windows-Azure-Mobile-Services
iOS: http://chrisrisner.com/Storing-Images-from-iOS-in-Windows-Azure-Mobile-Services
Due to the data types supported by Mobile Services, you'd need to store the image data as strings (varchars in the database). Again, far from the most efficient but it'll work.
I could create WriteableBitmap from pictures in Assets.
Uri imageUri1 = new Uri("ms-appx:///Assets/sample1.jpg");
WriteableBitmap writeableBmp = await new WriteableBitmap(1, 1).FromContent(imageUri1);
but, I can't create WriteableBitmap from Pictures Directory,(I'm using WinRT XAML Toolkit)
//open image
StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
StorageFile file = await picturesFolder.GetFileAsync("sample2.jpg");
var stream = await file.OpenReadAsync();
//create bitmap
BitmapImage bitmap2 = new BitmapImage();
bitmap2.SetSource();
bitmap2.SetSource(stream);
//create WriteableBitmap, but cannot
WriteableBitmap writeableBmp3 =
await WriteableBitmapFromBitmapImageExtension.FromBitmapImage(bitmap2);
Is this correct ?
This is a total contrivance, but it does seem to work ...
// load a jpeg, be sure to have the Pictures Library capability in your manifest
var folder = KnownFolders.PicturesLibrary;
var file = await folder.GetFileAsync("test.jpg");
var data = await FileIO.ReadBufferAsync(file);
// create a stream from the file
var ms = new InMemoryRandomAccessStream();
var dw = new Windows.Storage.Streams.DataWriter(ms);
dw.WriteBuffer(data);
await dw.StoreAsync();
ms.Seek(0);
// find out how big the image is, don't need this if you already know
var bm = new BitmapImage();
await bm.SetSourceAsync(ms);
// create a writable bitmap of the right size
var wb = new WriteableBitmap(bm.PixelWidth, bm.PixelHeight);
ms.Seek(0);
// load the writable bitpamp from the stream
await wb.SetSourceAsync(ms);
Here's the way reading an image to a WriteableBitmap works as Filip noted:
StorageFile imageFile = ...
WriteableBitmap writeableBitmap = null;
using (IRandomAccessStream imageStream = await imageFile.OpenReadAsync())
{
BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(
imageStream);
BitmapTransform dummyTransform = new BitmapTransform();
PixelDataProvider pixelDataProvider =
await bitmapDecoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied, dummyTransform,
ExifOrientationMode.RespectExifOrientation,
ColorManagementMode.ColorManageToSRgb);
byte[] pixelData = pixelDataProvider.DetachPixelData();
writeableBitmap = new WriteableBitmap(
(int)bitmapDecoder.OrientedPixelWidth,
(int)bitmapDecoder.OrientedPixelHeight);
using (Stream pixelStream = writeableBitmap.PixelBuffer.AsStream())
{
await pixelStream.WriteAsync(pixelData, 0, pixelData.Length);
}
}
Note that I am using the pixel format and alpha mode Writeable Bitmap uses and that I pass .
WriteableBitmapFromBitmapImageExtension.FromBitmapImage() works by using the original Uri used to load BitmapImage and IIRC it only works with BitmapImages from the appx. In your case there isn't even a Uri since loading from Pictures folder can only be done by loading from stream, so your options from the fastest to slowest (I think) are:
Open the image as WriteableBitmap from the get go, so that you don't need to reopen it or copy bits around.
If you need to have two copies - open it as WriteableBitmap and then create a new WriteableBitmap of same size and copy the pixel buffer.
If you need to have two copies - track the path used to open the first bitmap and then create a new WriteableBitmap by loading it from the same file as the original one.
I think option 2 might be faster than option 3 since you avoid decoding a compressed image twice.
My ImageHandler.ashx is not working when the webpart is calling it. any ideas on what is the correct way on calling or adding a handler in sharepoint? Thanks in advance
Here My ImageHandler.ashx code
byte[] buffer = (byte[])image.ImageData;
context.Response.ContentType = "image/jpeg";
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
In my webpart
imgcontrol.ImageUrl = "ImageHandler.aspx?id=1";
Check the Location where you have Deployed the ImageHandler.ashx. I have done similar thing in past and was able to get it working without any issues.
I deployed to _Layouts folder
imgcontrol.ImageUrl="_Layouts\x.ashx";
I assume that the code in your question is just a typo.
imgcontrol.ImageUrl = "ImageHandler.ashx?id=1";
this is a fragment from my own image handler that we use to load map pins in a sharepoint mapping webpart. We load the image, modify it, then return it.
Bitmap bmpPin = Bitmap.FromFile("myImageFile.jpg") as Bitmap
using (MemoryStream memStream = new MemoryStream())
{
this.m_Context.Response.ContentType = "image/png";
bmpPin.Save(memStream, ImageFormat.Png);
memStream.WriteTo(context.Response.OutputStream);
memStream.Close();
memStream.Dispose();
}
bmpPin.Dispose();