How to do MediaCapture in UWP application but not store in local machine - camera

I am developing an UWP application with a camera feature, I have studied this sets of codes,
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraStarterKit
And successfully developed a camera feature on my application. However, in my application, I wish to not store the picture into my local machine as the application is actually like a kiosk system whereby everyone will be using the same machine to take the picture.
What I am planning to do is actually to allow users to send the picture that they have taken to their own email address via the kiosk system. When they have taken a photo, a preview will be shown, and only if the user want to send the picture, then will the picture be "save"
The codes for my take photo function is something like this:
rivate async Task TakePhotoAsync()
{
var stream = new InMemoryRandomAccessStream();
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
try
{
var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(_rotationHelper.GetCameraCaptureOrientation());
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
Debug.WriteLine("Photo saved!");
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
}
And to get the preview of the picture will be:
private async Task GetPreviewFrameAsSoftwareBitmapAsync()
{
// Get information about the preview
var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
// Create the video frame to request a SoftwareBitmap preview frame
var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);
// Capture the preview frame
using (var currentFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame))
{
// Collect the resulting frame
SoftwareBitmap previewFrame = currentFrame.SoftwareBitmap;
// Show the frame information
FrameInfoTextBlock.Text = String.Format("{0}x{1} {2}", previewFrame.PixelWidth, previewFrame.PixelHeight, previewFrame.BitmapPixelFormat);
// Create a SoftwareBitmapSource to display the SoftwareBitmap to the user
var sbSource = new SoftwareBitmapSource();
await sbSource.SetBitmapAsync(previewFrame);
// Display it in the Image control
PreviewFrameImage.Source = sbSource;
}
}

There are (at least) two ways:
1) "Better" one:
Create a backend that sends email using SmtpClient
Post your image from UWP to backend using HttpClient
2) "Easier" one: launch Mail app
The downside is that users will be able to edit the message, receiver and things like that.
Also you can try to use SmtpClient directly from UWP client (may be now with .Net Standard 2.0 it would be possible but I guess no one yet tried) or third-party open-source replacement (which might be a bit outdated as it was created for Windows 8) or even try to launch your backend as Windows Service on the client machine.

Related

How do you send a pdf file using bot framework on a Skype channel?

I would like to send a pdf file using bot-framework on a Skype channel. Similar to how this is done on a telegram channel. Bot Framework: send pdf file on Telegram. I am really struggling to find useful documentation on using the Skype channel with bot-framework. CardAttachments don't work even though they were coming soon two years ago. Like the Telegram example, I have the pdf as a base64 string. I can't use a link as the pdf is generated from the user's inputs.
This is how I send images. I assume it is something similar.
var cardAttachment = new Attachment()
{
ContentUrl = "https://my.url/file.png",
ContentType = "image/png",
Name = "filename.png",
};
var reply = turnContext.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
reply.Text = "Some useful text to go along with the image.";
await turnContext.SendActivityAsync(reply, cancellationToken);
I tried
var values = new Dictionary<string, string>();
...
var content = new FormUrlEncodedContent(values);
var response = await Client.PostAsync(#"https://my.url/report.php", content);
var report = await response.Content.ReadAsByteArrayAsync();
var cardAttachment = new Attachment()
{
ContentUrl = "data:application/pdf;base64," + Convert.ToBase64String(report),
ContentType = "application/pdf",
Name = $"{answers.Name}.pdf",
};
var reply = turnContext.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
reply.Text = $"{answers.Name} here is your report.";
await turnContext.SendActivityAsync(reply, cancellationToken);
It seems to be close but quite right.
Update: While Skype blocks you from sending PDFs as attachments in any form (links, local file or Base64Strings) you can send them as links by simply embedding the link in your text. It looks like you can send links and local files to WebChat. Sending Bot Reply message with attachment using Bot Framework has lots of examples of various approaches.
I know as of this time last year, the Skype channel did not support sending PDF attachments to users due to security concerns - you can see more details regarding this problem here. I haven't been able to find any recent documentation contrary to that, nor was I able to send a PDF attachment through my test bot to Skype. I could, hower, send a PDF to the Emulator and WebChat. Unfortunately, I believe sending PDF attachments is still unsupported by the Skype channel.
Here is the sample code I used to send a PDF attachment to the emulator and WebChat:
var reply = turnContext.Activity.CreateReply();
// Create an attachment.
var attachment = new Attachment
{
ContentUrl = "<path_to_file>/<filename>.pdf",
ContentType = "application/pdf",
Name = "<filename>.pdf",
};
// Add the attachment to our reply.
reply.Attachments = new List<Attachment>() { attachment };
// Send the activity to the user.
await turnContext.SendActivityAsync(reply, cancellationToken);
Sorry I could not have been of more help.
While Skype blocks you from sending PDFs as attachments in any form (links, local file or Base64Strings) you can send them as links by simply embedding the link in your text.

Open Camera app installed from a UWP app and capture image

Instead of creating a Windows built-in camera UI (CameraCaptureUI) or using a custom MediaCapture control and capture picture I want to open any Camera App downloaded in the device to capture an image and get the result.
I have used
string uriToLaunch = "microsoft.windows.camera:";
var uri = new Uri(uriToLaunch);
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
But this just opens the camera app, I need to get the result file back to the app and save it.
Is there a way to do this?
The method you are using:
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
just opens the default camera, nothing more, the result is a boolean with information if the application has been opened successfully, nothing more.
With CameraCaptureUI you don't need to create camera - this seems to be designed for the task like you have described. With lines:
var captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200);
var photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
you just launch the camera app and your app waits for the photo, which you can process further/save.
If you don't want to use it or implement own camera capture, you can think of sharing a picture taken by other app. This is described well at app-to-app communication at MSDN. In this case user will have to click Share button and choose your app as a target. That will invoke OnShareTargetActivated event where you can process the received content.

Captured photos are black when using MediaCapture on Windows Phone 8.1

I am using MediaCapture to capture photos and store them. It works in the emulator. But when running the app on a real phone (Nokia Lumia 530) the captured photos are just black. They have a correct size and the file has a certain byte length, but when displaying the photo it's black. Please note that I do not use Silverlight and am fixed on using MediaCapture. The camera on the phone works when using the default camera app. The App's manifest includes the capabilities "Pictures Library" and "Webcam".
Does someone know what could be wrong?
Here is the test code I use:
using (var mediaCapture = new MediaCapture())
{
await mediaCapture.InitializeAsync();
ImageEncodingProperties imageFormat = ImageEncodingProperties.CreateJpeg();
StorageFile photoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("TestPhoto.jpg", CreationCollisionOption.GenerateUniqueName);
await mediaCapture.CapturePhotoToStorageFileAsync(imageFormat, photoFile);
BitmapImage bitmap = new BitmapImage();
using (var photoStream = await photoFile.OpenReadAsync())
{
bitmap.SetSource(photoStream);
}
}
Edit
I found a solution. The photo is captured correctly if we have a CaptureElement, set it's source to the MediaCapture object, invoke MediaCapture.StartPreviewAsync before taking the photo, take the photo (using CapturePhotoToStorageFileAsync) and finally invoke StopPreviewAsync. It seems that MediaCapture needs an existing (and displayed) preview to be able to capture photos. Strange that this is not documented and using CapturePhotoToStorageFileAsync without a preview does not throw an Exception.
The photo is captured correctly if we have a CaptureElement, set it's source to the MediaCapture object, invoke MediaCapture.StartPreviewAsync before taking the photo, take the photo (using CapturePhotoToStorageFileAsync) and finally invoke StopPreviewAsync. It seems that MediaCapture needs an existing (and displayed) preview to be able to capture photos. Strange that this is not documented and using CapturePhotoToStorageFileAsync without a preview does not throw an Exception.

Windows 8 Store MonoGame - How to extract bitmap from Camera

I am creating windows 8 store application with MonoGame framework. I want to get each bitmap from camera in order to process some image recognition on that bitmap. The thing is I only get the whole video stream from camera (randomAccessStream) but not each frame from the video.
async private void Start_Click(object sender, RoutedEventArgs e)
{
//1. Initialize:
mediaCaptureMgr = new MediaCapture();
randomAccessStream = new InMemoryRandomAccessStream();
await mediaCaptureMgr.InitializeAsync();
//2. create profile
MediaEncodingProfile encordingProfile = MediaEncodingProfile.CreateWmv(VideoEncodingQuality.Auto);
//3. start recording
await mediaCaptureMgr.StartRecordToStreamAsync(encordingProfile, randomAccessStream);
}
How can I receive new up-coming frame/bitmap from camera?
Take a look here
It is a sample app from Microsoft. Among other things it shows:
How to capture an image using the new LowLagPhotoCapture and LowLagPhotoControl classes.
How to capture a sequence of photos using the new LowLagPhotoSequenceCapture and LowLagPhotoSequenceControl classes.
...
If you are going to process the images, you could just take pictures on an interval. I don't think you need to process every single frame of a video stream..

Can Adobe AIR Desktop application take full screen snapshots (aka Print Screen button)

I would like to know if its possible to get full screen snapshots from an air application.
What i am interested in, is functionality similar to PrintScreen button in windows, which takes snapshots of all screens, including third party application windows, not just window in which air app is running.
If its not specific to air, and flash/flex API can provide such functionality, it also would be great.
Thanx a lot in advance.
Check out this article as it explains obtaining a screenshot by calling a native process:
import flash.filesystem.File;
import flash.events.NativeProcessExitEvent;
var process:NativeProcess;
if(NativeProcess.isSupported) {
var file:File = File.applicationDirectory;
var args:Vector.<String> = new Vector.<String>();
if (Capabilities.os.toLowerCase().indexOf("win") > -1) {
file = file.resolvePath("PATH/TO/WINDOWS/printscr");
//use your prefered screenshot tool here (e.g. https://code.google.com/p/screenshot-cmd/
//also setup the args as needed
} else if (Capabilities.os.toLowerCase().indexOf("mac") > -1) {
file = file.resolvePath("/usr/sbin/screencapture");
args[0] = "-i";
args[1] = "screencapture.png";
}
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.arguments = args;
nativeProcessStartupInfo.executable = file;
nativeProcessStartupInfo.workingDirectory = File.desktopDirectory;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(NativeProcessExitEvent.EXIT,done);
}else trace("NativeProcess NOT SUPPORTED!");
function done(e:NativeProcessExitEvent):void{
trace("screenshot comprete");
}
One important thing to bear in mind is the AIR device profile.
If you're initially testing in ADL, be sure to use the extendedDesktop profile, otherwise NativeProcess.isSupported will return false.
For more details check out the NativeProcess documentation and the Communicating with native processes in AIR developer guide