BitmapDecoder .GetPixelDataAsync(params) changing the orientation of captured image - windows-phone-8.1

I am working with an UWP app and facing an issue while displaying a camera captured image(Portrait) in an image control.If I use parmaterized version
decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Ignore,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage);
The outcome is image with change in orientation of 90 degree in anticlock direction. //Issue
Oriented Normal
However default decoder.GetPixelDataAsync();works fine.
Problem here is I cannot use default version of GetPixelDataSync() as I need to scale the image using BitmapTransformation.
Please help.
Complete Code:
public async Task PrepareCapturedImage(StorageFile originalFile)
{
try
{
BitmapImage capturedImage_ = new BitmapImage();
BitmapDecoder decoder = null;
// the image is sometimes not created and we are trying to access it
await Task.Delay(300);
using (IRandomAccessStream stream = await originalFile.OpenAsync(FileAccessMode.Read))
{
capturedImage_.SetSource(stream);
decoder = await BitmapDecoder.CreateAsync(stream);
}
BitmapTransform transform = new BitmapTransform();
uint newHeight = Convert.ToUInt32(capturedImage_.PixelHeight);
uint newWidth = Convert.ToUInt32(capturedImage_.PixelWidth);
transform.ScaledHeight = newHeight;
transform.ScaledWidth = newWidth;
PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Ignore,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage);
// An array containing the decoded image data, which could be modified before being displayed
byte[] sourcePixels = pixelData.DetachPixelData();
using (InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream())
{
BitmapEncoder enc = null;
BitmapPropertySet propertySet = new BitmapPropertySet();
enc = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras, propertySet);
// write the pixel data to our stream
enc.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, newWidth, newHeight, decoder.DpiX, decoder.DpiY, sourcePixels);
await enc.FlushAsync();
ras.Seek(0);
BitmapImage image = new BitmapImage();
image.SetSource(ras);
cameraOutputImage.Source = image;
}
}
catch (Exception ex)
{
}
}

Related

Blur images in Windows Runtime C# using WriteableBitmapEx

I am trying to blur an image in my new Windows Phone Runtime C# app (WPRT)
I used WriteableBitmapEx NuGet and this code to make my image blured but can't see any changes in my picture . what's going wrong guys ?
public TestXaml()
{
this.InitializeComponent();
....
test();
}
async void test()
{
var ImgFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/TestBG.jpg"));
var wb = new WriteableBitmap(100,100);
using (var strm = await ImgFile.OpenReadAsync())
{
wb = await wb.FromStream(strm);
}
var wb3 = WriteableBitmapExtensions.Convolute(wb, WriteableBitmapExtensions.KernelGaussianBlur5x5);
ImageBrush ib = new ImageBrush();
ib.ImageSource = wb3;
PageBackground.Background = ib;
}
also I tried WriteableBitmapExtensions.KernelGaussianBlur3x3 but still no change

Play part of an audio file

I have to play an audio part out of a big file (300MB+).
This is my code:
// Media source is a local file.
// datName = "sound.dat"
// pointer = position in file
// length = length of the part to play
try
{
file = await StorageFile.GetFileFromApplicationUriAsync
(new Uri(#"ms-appx:///Data/" + datName));
// Get the media source as a stream.
IRandomAccessStream stream =
await file.OpenAsync(FileAccessMode.Read);
stream.Seek((ulong)pointer); // This is working, position changes from 0 to pointer
stream.Size = (ulong)length; // Is not working, Size remains unchanged at total file size
media.SetSource(stream, file.ContentType);
media.Play();
}
catch (Exception ex)
{
if (ex is FormatException || ex is ArgumentException)
{
//ShowFileErrorMsg();
}
}
Please note the comments on stream Seek and Size. The file is played from position zero.
How can I play the sound from pointer to pointer + length?
I've solved my problem by using the binary reader. I read the required area in a byte buffer and convert it to an IRandomAccessStream.
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(#"ms-appx:///Data/" + fileName));
using (Stream stream = (await file.OpenReadAsync()).AsStreamForRead())
using (BinaryReader reader = new BinaryReader(stream))
{
reader.BaseStream.Position = pointer;
byte[] buffer = reader.ReadBytes((int)length);
IRandomAccessStream nstream = new MemoryStream(buffer).AsRandomAccessStream();
media.SetSource(nstream, "");
media.Play();
}
This version is now working.

Refresh an ObservableCollection when Item's property changed

I have a observableCollection which is loaded with elements and displayed on the UI .At the same time the app is downloading one Icon for each element of the observable collection.I would like to display each Icon when its download finishes...
My code is working but i guess it's not the best pratice because I bind my collection to the Ui control 2 times...I am pretty convinced that it shouldn't be necessary ...I try to implement the InotifypropertyChanged on the element's Icon property but I still have to add those lines of code to display the Icons:
listDocsLibs = new ObservableCollection<BdeskDocLib>(listBoxGetDocsLibs);
llslistDocslibs.ItemsSource = listDocsLibs;
Below the function which dowload the Icons
List<BdeskDocLib> listBoxGetDocsLibs = new List<BdeskDocLib>();
ObservableCollection<BdeskDocLib> listDocsLibs = new ObservableCollection<BdeskDocLib>();
private async void LoadIconDocLibs()
{
foreach (var doclib in listBoxGetDocsLibs)
{
byte[] Icon = await ServerFunctions.GetDocLibsIcon(doclib);
if (Icon != null)
{
{
var ms = new MemoryStream(Icon);
BitmapImage photo = new BitmapImage();
photo.DecodePixelHeight = 64;
photo.DecodePixelWidth = 92;
photo.SetSource(ms);
doclib.Icon = photo;
}
}
else if (Icon == null)
{
doclib.Icon = new BitmapImage();
doclib.Icon.UriSource = new Uri("/Images/BDocs/ico_ext_inconnu.png", UriKind.Relative);
}
}
}
//IM PRETTY SURE The following code IS NOT NECESSARY BUT WHY MY UI IS NOT REFRESHING WITHOUT ?
listDocsLibs = new ObservableCollection<BdeskDocLib>(listBoxGetDocsLibs);
llslistDocslibs.ItemsSource = listDocsLibs;
}

Get a uri from a LocalStorage in Windows Phone

I write the following code to save some images from internet:
public static async Task SaveImage(string name, string uri)
{
var localfolder = ApplicationData.Current.LocalFolder;
var client = new HttpClient();
var imageStream = await client.GetStreamAsync(uri); //Secuencia de bytes
var storageFile = await localfolder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);
using (Stream outputStream = await storageFile.OpenStreamForWriteAsync())
{
await imageStream.CopyToAsync(outputStream);
}
}
My problem is when I try to set these images store in the Local Storage to a CycleTile because this class needs the Uri's, and I don't know how to provide the uri here. This is what I have:
CycleTileData cycleicon = new CycleTileData();
cycleicon.Title = "Fotopantalla";
cycleicon.Count = 0;
cycleicon.SmallBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileSmall.png", UriKind.RelativeOrAbsolute);
List<Uri> images = new List<Uri>();
for (int i = 0; i < 9; i++)
{
/// tries...
string path1 = "ms-appdata:///local/image" + i + ".jpg";
string path2 = "isostore:/Shared/ShellContent/image" + i + ".jpg";
string path3 = "ms-appdata:///Local/Shared/ShellContent/image" + i + ".jpg";
///
Uri uri = new Uri(path2, UriKind.RelativeOrAbsolute);
images.Add(uri);
}
cycleicon.CycleImages = images;
What am I wrong or what am I missing?
For any ShellTileData related data structures you have to use path2:
"isostore:/Shared/ShellContent/*" if the images are not in the (read only) InstalledLocation folder.
For more details see: http://blogs.msdn.com/b/andy_wigley/archive/2013/04/10/live-apps-creating-custom-tile-and-lock-screen-images.aspx
I have something similar in my code:
var store = IsolatedStorageFile.GetUserStoreForApplication();
if (!store.DirectoryExists("Shared/ShellContent"))
{
store.CreateDirectory("Shared/ShellContent");
}
StorageFolder shellContent = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFolderAsync("Shared", CreationCollisionOption.OpenIfExists);
shellContent = await shellContent.CreateFolderAsync("ShellContent", CreationCollisionOption.OpenIfExists);
Stream imgin = picture.GetImage();
//Picture read stream from Media Library or other input stream
StorageFile new_img = await shellContent.CreateFileAsync(newPictureName);
Stream imgout = await new_img.OpenStreamForWriteAsync();
imgin.CopyTo(imgout);
imgout.Close(); // <- necessary in your code or not?
imgin.Close(); // <-
I'm not sure, whether you really need the Isostore thing at the beginning, but it works, if I haven't done some stupid mistake while shortening the code. ;-)
Also have a look at "StandardTileData.BackgroundImage Property", "Data for Windows Phone" and "How to use the Isolated Storage Explorer tool for Windows Phone" from Microsoft's Dev Center. (The last one is about how to have a look at the saved image file on your device.)

QrCode Open Source Library for WinRT

I need to generate the Qr Code for my Windows 8 Store App.Is there any Open Source Qr Code Library which is based on Win Rt.
I have made use of zxing library which is available on codeplex.
The method I wrote is as follows:
I'm making use of the DecodeQRcode with storage file from the camera's CaptureFileAsync method which returns the storage file of the qrImgage.
public async void DecodeQRCode(StorageFile file)
{
// load a jpeg, be sure to have the Pictures Library capability in your manifest
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);
var lsource = new BitmapLuminanceSource(wb);
var binarizer = new HybridBinarizer(lsource);
var bbmp = new BinaryBitmap(binarizer);
var c = new QRCodeReader();
Result res= c.decode(bbmp);
}
While taking the image of the QR code you must make sure that you crop the image properly or else you won't get the expected result.
I have not used this, but ZXing.Net is....
A library which supports decoding and generating of barcodes (like QR
Code, PDF 417, EAN, UPC, Aztec, Data Matrix, Codabar) within images.
and has assembles available for WindowsRT (as well as phone)
You can use the ZXing.NET: https://zxingnet.codeplex.com/
Code for load image to get QR Code result:
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".png");
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".bmp");
StorageFile file = await openPicker.PickSingleFileAsync();
if (null != file)
{
try
{
BitmapImage bitmap = new BitmapImage();
using (IRandomAccessStream fileStream1 = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
bitmap.SetSource(fileStream1);
}
using (IRandomAccessStream fileStream2 = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight);
writeableBitmap.SetSource(fileStream2); IBarcodeReader reader = new BarcodeReader();
var result = reader.Decode(writeableBitmap);
txt1.Text = result.ToString();
}
}
catch (Exception exception)
{
//
}
}
Code for get QR from camera (use the MSDN demo: http://code.msdn.microsoft.com/windowsapps/CameraCaptureUI-Sample-845a53ac and customized):
private async void CapturePhoto_Click(object sender, RoutedEventArgs e)
{
try
{
rootPage.NotifyUser("", NotifyType.StatusMessage);
// Using Windows.Media.Capture.CameraCaptureUI API to capture a photo
CameraCaptureUI dialog = new CameraCaptureUI();
Size aspectRatio = new Size(1, 1);
dialog.PhotoSettings.CroppedAspectRatio = aspectRatio;
StorageFile file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (file != null)
{
BitmapImage bitmapImage = new BitmapImage();
using (IRandomAccessStream fileStream1 = await file.OpenAsync(FileAccessMode.Read))
{
bitmapImage.SetSource(fileStream1);
}
CapturedPhoto.Source = bitmapImage;
ResetButton.Visibility = Visibility.Visible;
ZXing.BarcodeReader br = new ZXing.BarcodeReader();
WriteableBitmap wrb = new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
BitmapImage img = new BitmapImage();
img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
using (IRandomAccessStream fileStream2 = await file.OpenAsync(FileAccessMode.Read))
{
wrb.SetSource(fileStream2);
}
var res = br.Decode(wrb);
rootPage.NotifyUser(res.ToString(), NotifyType.ErrorMessage);
}
else
{
rootPage.NotifyUser("No photo captured.", NotifyType.StatusMessage);
}
}
catch (Exception ex)
{
rootPage.NotifyUser(ex.Message, NotifyType.ErrorMessage);
}
}