I am working on an application for working with photos for Windows 8 Metro on C#. And now I'm faced with a strange problem.
First, I select the file over PickSingleFileAsync, then trying to get a thumbnail via GetThumbnailAsync:
FileOpenPicker openPicker = new FileOpenPicker ();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add (". jpg");
openPicker.FileTypeFilter.Add (". jpeg");
openPicker.FileTypeFilter.Add (". png");
StorageFile file = await openPicker.PickSingleFileAsync ();
if (file! = null)
{
BitmapImage bitmapImage = new BitmapImage ();
var thumb = await file.GetThumbnailAsync (ThumbnailMode.PicturesView, 150, ThumbnailOptions.UseCurrentScale);
if (thumb! = null) bitmapImage.SetSource (thumb);
}
This code is executed for files on my HDD or for any MTP-devices (tested camera and Android Tablet), but not for the iPhone. This part
var thumb = await file.GetThumbnailAsync (ThumbnailMode.PicturesView, 150, ThumbnailOptions.UseCurrentScale);
Performed for about 30 seconds, and returns null.
This code
BitmapImage bitmapImage = new BitmapImage ();
var stream = await file.OpenAsync (FileAccessMode.Read);
if (stream! = null) bitmapImage.SetSource (stream);
However, this is a complete picture, and I need a thumbnail. I tried to get it by changing the image size.
public static async Task <InMemoryRandomAccessStream> Resize (StorageFile file, uint height, uint width)
{
var fileStream = await file.OpenAsync (FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync (fileStream);
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream ();
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync (ras, decoder);
enc.BitmapTransform.ScaledHeight = height;
enc.BitmapTransform.ScaledWidth = width;
await enc.FlushAsync ();
ras.Seek (0);
return ras;
}
And there
BitmapDecoder decoder = await BitmapDecoder.CreateAsync (fileStream);
Exception "The image cannot be decoded" occurs with code 0x88982F61.
FileOpenPicker also does not display thumbnail images on the iPhone.
But standart Photos app for Metro shows all photos on iPhone without problems.
And this leads me to 2 question:
Does anyone have any suggestions to fix this problem?
Maybe, is there a function to retrieve all the thumbnails from device?
Related
I have to make parallel work (of course async Task) that blur images selected from folder, so I have found this (BitmapImage), but the problem is what i do not know how to access bytes or pixels of this object, so that I can change them, blur or something else:
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
folderPicker.FileTypeFilter.Add(".jpg");
folderPicker.FileTypeFilter.Add(".jpeg");
folderPicker.FileTypeFilter.Add(".png");
var folder = await folderPicker.PickSingleFolderAsync();
var filesList = await folder.GetFilesAsync();
for (int i = 0; i < filesList.Count; i++)
{
using (var stream = await filesList[i].OpenAsync(Windows.Storage.FileAccessMode.Read))
{
//Here I will use some array of BitmapImage
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
await bitmapImage.SetSourceAsync(stream);
//show Image on Form
imageSourceForm.Source = bitmapImage;
}
}
So is there any way to get pixels or bytes of this object, or maybe do you know what to use that I can do work, but with async Task. The most important part is that UI Thread has to be responsive, while the images are blurring. Thanks in advance.
You could use the following code to get bytes of an image:
var random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(filesList[i]).OpenReadAsync();
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(random);
Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
//Access pixel buffer in such a way
byte[] bytes = pixelData.DetachPixelData();
I'm working on windows phone 8.1 application. I have different pictures locally in app and displaying those pictures in list view. Now select one picture id and pass it to detail screen, where I have to save that file .
My detail.Xaml screen contain image control named as Imaged.
I got image on detail page and press image save button. I'm using this Sample app https://code.msdn.microsoft.com/windowsapps/Save-Edited-Picture-16d910c4/sourcecode?fileId=119937&pathId=946309183 "Sample"
My detail page Code is here.
string tempimg;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var imagePath = e.Parameter as string;
imaged.Source = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute));
tempimg = imagePath;
}
My SaveImage button code is here.
if (tempimg == null)
return;
// WriteableBitmap abc = new WriteableBitmap(400, 400);
string filename = "Image-" + DateTime.Now.ToFileTime() + ".jpeg";
// await SaveWriteableBitmapAsJpeg(img, filename);
Blockquote
await SaveWriteableBitmapAsJpeg(tempimg, filename);
private static async Task SaveWriteableBitmapAsJpeg(WriteableBitmap bmp, string fileName)
{
// Create file in Pictures library and write jpeg to it
var outputFile = await KnownFolders.CameraRoll.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
await EncodeWriteableBitmap(bmp, writeStream, BitmapEncoder.JpegEncoderId);
}
}
private static async Task EncodeWriteableBitmap(WriteableBitmap bmp, IRandomAccessStream writeStream, Guid encoderId)
{
// Copy buffer to pixels
byte[] pixels;
using (var stream = bmp.PixelBuffer.AsStream())
{
pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);
}
// Encode pixels into stream
var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied,
(uint)bmp.PixelWidth, (uint)bmp.PixelHeight,
96, 96, pixels);
await encoder.FlushAsync();
}
My this function "await SaveWriteableBitmapAsJpeg(tempimg, filename);" creates a problem. I just have the image source while that require the writeablebitmap. I just want to save image and not able to proceed from here. let me know the exact solution or problem.
I need to get Thumbnail from mp3 files. I Implemented this but it never catch thumbnails. I checked the existence of the images opening them with windows media player and from xbox music (on the phone) but i can't retrieve them in my app. Please Help
async private void ThumbnailFetcher(StorageFile file)
{
if (file != null)
{
const ThumbnailMode thumbnailMode = ThumbnailMode.MusicView;
const uint size = 100;
using (StorageItemThumbnail thumbnail = await file.GetThumbnailAsync(thumbnailMode, size))
{
if (thumbnail != null && thumbnail.Type == ThumbnailType.Image)
{
this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
BitmapImage thumbnailImage = new BitmapImage();//image used for display
thumbnailImage.SetSource(thumbnail);
CurrentAlbumArt.Source = thumbnailImage;
Debug.WriteLine("true");
});
}
else
{
Debug.WriteLine("False");
}
}
}
}
P.s It gives always false.
It seems there is a bug on windows phone 8.1, I searched all the night and the only method I could implemented is this
var fileStream = await file.OpenStreamForReadAsync();
var TagFile = File.Create(new StreamFileAbstraction(file.Name, fileStream, fileStream));
// Load you image data in MemoryStream
var tags = TagFile.GetTag(TagTypes.Id3v2);
IPicture pic = TagFile.Tag.Pictures[0];
MemoryStream ms = new MemoryStream(pic.Data.Data);
ms.Seek(0, SeekOrigin.Begin);
bitmap.SetSource(ms.AsRandomAccessStream());
AlbumArt.Source = bitmap;
but it doesn't work too..
var filestream = await receivedFile.OpenStreamForReadAsync();
var tagFile = File.Create(new StreamFileAbstraction(receivedFile.Name, filestream, filestream));
var tags = tagFile.GetTag(TagLib.TagTypes.Id3v2);
var bin = (byte[])(tags.Pictures[0].Data.Data);
MemoryStream ms = new MemoryStream(bin);
await bitmapImage.SetSourceAsync(ms.AsRandomAccessStream());
AlbumArt.Source=bitmapImage;
use this and taglib portable. (Sorry for take so much time)
In my windows app, i am trying to load an image from local machine to server but facing an exception of System.Runtime.InteropServices.COMException on the statement StorageFile file = await open.PickSingleFileAsync();. Here is the method:
FileOpenPicker open = new FileOpenPicker();
StorageFile file = await open.PickSingleFileAsync();
if (file != null)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.DecodePixelWidth = 600; //match the target Image.Width, not shown
await bitmapImage.SetSourceAsync(fileStream);
big_image.Source = bitmapImage;
}
}
How to fix it ??? I am using VS '13. Big_image is the image defined in xaml and i am trying to set its source.
i got the solution by adding some new stuff:
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
big_image.Source = bitmapImage;
}
}
microsoft.phone.tasks.photochoosertask is used to pick images.
With the following code I can get a IRandomAccessStreamWithContentType representing the Thumbal of a contact
var contactPicker = new ContactPicker();
contactPicker.SelectionMode = ContactSelectionMode.Contacts;
var contact = await contactPicker.PickSingleContactAsync();
var thumb = await contact.GetThumbnailAsync();
But what is the best way to handle the IRandomAccessStreamWithContentType to get a image instance and a imagefile ?
You should just handle it as an ordinary IRandomAccessStream containing the image:
using (var stream = await contact.GetThumbnailAsync())
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
BitmapFrame frame = await decoder.GetFrameAsync(0);
var bitmap = new WriteableBitmap((int)frame.PixelWidth, (int)frame.PixelHeight);
stream.Seek(0);
await bitmap.SetSourceAsync(stream);
}
From here on you can set the WriteableBitmap as asource to Image control or use it in any other way.
The Seek call is required because the stream is already read to get the image size so the position needs to be reset before reading the image itself.