I'm having great difficulty getting my captured image to be rotated correctly, the bitmapencoder class doesn't seem to be doing anything.
private async Task CapturePhoto()
{
ImageEncodingProperties pIEPEncoder = ImageEncodingProperties.CreateJpeg();
InMemoryRandomAccessStream pIMSCapture = new InMemoryRandomAccessStream();
using (pIMSCapture)
{
await cMCeCapture.CapturePhotoToStreamAsync(pIEPEncoder, pIMSCapture);
pIMSCapture.Seek(0);
BitmapDecoder pBDrDecoder = await BitmapDecoder.CreateAsync(pIMSCapture);
BitmapEncoder pBErEncoder = await BitmapEncoder.CreateForTranscodingAsync(pIMSCapture, pBDrDecoder);
pBErEncoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
pBErEncoder.BitmapTransform.Rotation = ConvertDegreesToBitmapRotation(cIntRotationDegrees);
await pBErEncoder.FlushAsync();
BitmapImage pBIeCapture = new BitmapImage();
pIMSCapture.Seek(0);
await pBIeCapture.SetSourceAsync(pIMSCapture);
CaptureImage.Source = pBIeCapture;
CaptureImage.Stretch = Stretch.Uniform;
CaptureImage.Width = LayoutRoot.ActualWidth;
CaptureImage.Height = LayoutRoot.ActualHeight;
}
await CleanupCameraAsync();
}
Any ideas how to fix this? The camera API seems to be my nemesis as of late, so frustrating to get anything working how I would like.
I have found an alternative solution and that's to use the WritableBitmapEx class obtained from here,
https://writeablebitmapex.codeplex.com/
This actually does what it's supposed to do, unlike the BitmapEncoder class for some reason. Plus it's super easy to use. Although flipping Horizontal seems to flip Vertical instead, not entirely sure why but it works anyway. I just switched Horizontal and Vertical over.
private async Task CapturePhoto()
{
ImageEncodingProperties pIEPEncoder = ImageEncodingProperties.CreateJpeg();
InMemoryRandomAccessStream pIMSCapture = new InMemoryRandomAccessStream();
using (pIMSCapture)
{
await cMCeCapture.CapturePhotoToStreamAsync(pIEPEncoder, pIMSCapture);
if(!cBlnExternalCamera)
{
pIMSCapture.Seek(0);
BitmapImage pBIeCapture = new BitmapImage();
await pBIeCapture.SetSourceAsync(pIMSCapture);
pIMSCapture.Seek(0);
WriteableBitmap pWBpBitmap = new WriteableBitmap(pBIeCapture.PixelWidth, pBIeCapture.PixelHeight);
await pWBpBitmap.SetSourceAsync(pIMSCapture);
if (cIntRotationDegrees != 0)
pWBpBitmap = pWBpBitmap.Rotate(cIntRotationDegrees);
if (cBlnMirroringPreview)
pWBpBitmap = pWBpBitmap.Flip(cDInDisplayInformation.CurrentOrientation == DisplayOrientations.Landscape || cDInDisplayInformation.CurrentOrientation == DisplayOrientations.LandscapeFlipped ? WriteableBitmapExtensions.FlipMode.Vertical : WriteableBitmapExtensions.FlipMode.Horizontal);
CaptureImage.Source = pWBpBitmap;
CaptureImage.Stretch = Stretch.Uniform;
CaptureImage.Width = LayoutRoot.ActualWidth;
CaptureImage.Height = LayoutRoot.ActualHeight;
}
else
{
pIMSCapture.Seek(0);
BitmapImage pBIeCapture = new BitmapImage();
await pBIeCapture.SetSourceAsync(pIMSCapture);
CaptureImage.Source = pBIeCapture;
CaptureImage.Stretch = Stretch.Uniform;
CaptureImage.Width = LayoutRoot.ActualWidth;
CaptureImage.Height = LayoutRoot.ActualHeight;
}
}
await CleanupCameraAsync();
}
Related
I'm new to win8 app programming but has been assigned to write a windows store app to capture customers' signature and save it to SQL Server. After some research I found a great tutorial
http://www.codeproject.com/Articles/416878/Metro-Paint which shows how to draw and save the image locally. My question is how do I use the InkManager class in the tutorial to save the image to byte arrays so that I can save the image to SQLServer? Thanks!
private async void btnSaveWritingAsImage_Click(object sender, RoutedEventArgs e)
{
if (MyInkManager.GetStrokes().Count > 0)
{
try
{
Windows.Storage.Pickers.FileSavePicker SavePicker = new Windows.Storage.Pickers.FileSavePicker();
SavePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
SavePicker.DefaultFileExtension = ".png";
SavePicker.FileTypeChoices.Add("PNG", new string[] { ".png" });
SavePicker.FileTypeChoices.Add("JPG", new string[] { ".jpg" });
StorageFile filesave = await SavePicker.PickSaveFileAsync();
IOutputStream ab = await filesave.OpenAsync(FileAccessMode.ReadWrite);
if (ab != null)
await MyInkManager.SaveAsync(ab);
}
catch (Exception)
{
var MsgDlg = new MessageDialog("Only handwriting can be saved as image.", "Error while saving");
MsgDlg.ShowAsync();
}
}
else
{
var MsgDlg = new MessageDialog("Only handwriting can be saved as image.", "Error while saving");
await MsgDlg.ShowAsync();
}
}
add: (IBuffer.ToArray() is defined in WindowsRuntimeBufferExtensions)
using System.Runtime.InteropServices.WindowsRuntime;
then just do:
var buffer = await FileIO.ReadBufferAsync(image);//replace ab instead of image
var bytes = buffer.ToArray();
I'm tring to get the profile picture from People App. I used
Windows.ApplicationModel.Contacts.Contact contact = new Contact();
I got Thumbnail from propety contact.Thumbnail.
I need to convert this Thumbnail to StorageFile. Could you please give inputs to solve this issue?
And, while using the following code:
IRandomAccessStreamWithContentType stream = awaitcontactInfo.Thumbnail.OpenReadAsync();
if(stream != null && stream.Size > 0)
{
//
}
Sometimes I'm getting RPC Server is unavailable Exception. Sometimes the streamSize is Zero.
You are creating new instance of Contact class. You don't have to do that to pick contact from people. You should use ContactPicker.
var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
contactPicker.CommitButtonText = "Select";
ContactInformation contact = await contactPicker.PickSingleContactAsync();
if (contact != null)
{
IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync();
if (stream != null && stream.Size > 0)
{
var file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("MyContactThumb.png", CreationCollisionOption.GenerateUniqueName);
// You can also use FileSavePicker to save file in user defined location.
Windows.Storage.Streams.Buffer MyBuffer = new Windows.Storage.Streams.Buffer(Convert.ToUInt32(stream.Size));
IBuffer iBuf = await stream.ReadAsync(MyBuffer, MyBuffer.Capacity, InputStreamOptions.None);
await FileIO.WriteBufferAsync(file, iBuf);
}
}
I am creating Thumbnail and showing in frame by using this code
Platform -> windows 8 metro apps using c#
http://code.msdn.microsoft.com/windowsapps/File-and-folder-thumbnail-1d530e5d
in windows 8 metro apps using c#. i need to save or Store ( in device )the thumbnail image which i am creating at run time. in DisplayResult() of constants.cs class file i need to save that image in device how to achieve this . please give me some idea or example i am very new in mobile and never worked on Image and thumbnails Part . Thanks in advance .
Try this. The below code will save picked audio file's album art in TempFolder
private async void btnPickFile_Click(object sender, RoutedEventArgs e)
{
string[] Music = new string[] { ".mp3", ".wma", ".m4a", ".aac" };
FileOpenPicker openPicker = new FileOpenPicker();
foreach (string extension in Music)
{
openPicker.FileTypeFilter.Add(extension);
}
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
await SaveThumbnail("MySongThumb.png", file);
}
}
private async Task SaveThumbnail(string ThumbnailName, StorageFile file)
{
if (file != null)
{
using (StorageItemThumbnail thumbnail = await file.GetThumbnailAsync(ThumbnailMode.MusicView, 100))
{
if (thumbnail != null && thumbnail.Type == ThumbnailType.Image)
{
var destinationFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(ThumbnailName, CreationCollisionOption.GenerateUniqueName);
Windows.Storage.Streams.Buffer MyBuffer = new Windows.Storage.Streams.Buffer(Convert.ToUInt32(thumbnail.Size));
IBuffer iBuf = await thumbnail.ReadAsync(MyBuffer, MyBuffer.Capacity, InputStreamOptions.None);
using (var strm = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
{
await strm.WriteAsync(iBuf);
}
}
}
}
}
UPDATE 1
private async Task<StorageFile> SaveThumbnail(StorageItemThumbnail objThumbnail)
{
if (objThumbnail != null && objThumbnail.Type == ThumbnailType.Image)
{
var picker = new FileSavePicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.FileTypeChoices.Add("JPEG Image", new string[] { ".jpg" });
picker.FileTypeChoices.Add("PNG Image", new string[] { ".png" });
StorageFile destinationFile = await picker.PickSaveFileAsync();
if (destinationFile != null)
{
Windows.Storage.Streams.Buffer MyBuffer = new Windows.Storage.Streams.Buffer(Convert.ToUInt32(objThumbnail.Size));
IBuffer iBuf = await objThumbnail.ReadAsync(MyBuffer, MyBuffer.Capacity, InputStreamOptions.None);
using (var strm = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
{
await strm.WriteAsync(iBuf);
}
}
return destinationFile;
}
else
{
return null;
}
}
I used below code to capture photo but not sure how to save it in Picture Library or Folder in Picture Library. Would appreciate your help on this.
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
BitmapImage bmp = new BitmapImage();
IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
bmp.SetSource(stream);
ImageSource.Source = bmp;
ImageSource.Visibility = Visibility.Visible;
StorageFolder storageFolder = KnownFolders.PicturesLibrary;
??? not sure :
var imagefile = await KnownFolders.PicturesLibrary.CreateFileAsync("MyPhoto.jpeg", CreationCollisionOption.ReplaceExisting);
photo.CopyAsync(storageFolder,imagefile);
}
Here you go. You must have to set camera and picture library access capability in manifest.
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
//By default the photo will be stored at location
//%localappdata%\Packages\APP_PACKAGE_ID\TempState
if (photo != null)
{
//await photo.MoveAsync(KnownFolders.PicturesLibrary);
//OR
await photo.MoveAsync(KnownFolders.PicturesLibrary, "DesiredPhotoName" + photo.FileType, NameCollisionOption.GenerateUniqueName);
}
I am trying to make an app that applies filter effects on images. From FilePicker I can get a IRandomAccessStream and I can convert it to BitmapDecoder. But I am not sure how to diplay the bitmap data as image? I do not want to use the file name or path, just want to display the BitmapData as an image. What control should I use in WinJS and how to do it?
Convert an IInputStream or IRandomAccessStream to an image with MSApp.createStreamFromInputStream() and URL.createObjectURL():
var path = Windows.Storage.ApplicationData.current.localFolder.path + "\\thing.jpg";
Windows.Storage.StorageFile.getFileFromPathAsync(path).then(function (file) {
file.openAsync(Windows.Storage.FileAccessMode.read).then(function (randomStream) {
// Convert the stream to MS-Stream.
var msStream = MSApp.createStreamFromInputStream("image/jpeg", randomStream);
var imageUrl = URL.createObjectURL(msStream);
var img = document.getElementById("theImage");
img.src = imageUrl;
}, onError);
}, onError);
The HTML should look like this:
<img id="theImage" src="#" />
These MSDN blogs explain the following process in more detail
http://goo.gl/izCdf
http://goo.gl/OLgfn
I found a way to create a BitmapEncoder from a BitmapDecoder. That encoder can be used to create a in memory stream that can be displayed in a field.
internal async Task<InMemoryRandomAccessStream> applyFilterInternal()
{
inputStream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(inputStream);
var memStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
var encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateForTranscodingAsync(memStream, decoder);
encoder.BitmapTransform.ScaledWidth = 640;
encoder.BitmapTransform.ScaledHeight = 480;
encoder.BitmapTransform.Rotation = Windows.Graphics.Imaging.BitmapRotation.Clockwise90Degrees;
// Fant is a relatively high quality interpolation algorithm.
encoder.BitmapTransform.InterpolationMode = Windows.Graphics.Imaging.BitmapInterpolationMode.Fant;
// Attempt to generate a new thumbnail from the updated pixel data.
// Note: Only JPEG, TIFF and JPEG-XR images support encoding thumbnails.
encoder.IsThumbnailGenerated = true;
await encoder.FlushAsync();
return memStream;
}
public IAsyncOperation<InMemoryRandomAccessStream> applyFilter()
{
Task<InMemoryRandomAccessStream> from = applyFilterInternal();
IAsyncOperation<InMemoryRandomAccessStream> to = from.AsAsyncOperation();
return to;
}
To display this -
filter.applyFilter().then(function (memStream) {
var msStream = MSApp.createStreamFromInputStream("image/jpeg", memStream);
var imageURL = URL.createObjectURL(msStream);
id("imageInput").src = imageURL;
});