Taking photo in C++/CX with Windows Phone 8.1 - windows-phone-8.1

I am working in C++/CX (in Visual Studio 2013) on an app for Windows phone 8.1 systems. I test my app on a Nokia Lumia 930. My app must take photos to do some image processing on them. Therefore I would like to have a byte* or char* or unsigned char* to to whatever I want. So I tried to use ::Windows::Media::Capture::MediaCapture::CapturePhotoToStreamAsync to get the content of the photo into a stream and then with a ::Windows::Storage::Streams::DataReader get the actual bytes of the photo. But I have been unsuccessful. More precisely the problem is here in the code that follows.
IRandomAccessStream ^ras = ref new InMemoryRandomAccessStream();
IAsyncAction ^ac = cap->CapturePhotoToStreamAsync(ImageEncodingProperties::CreateBmp(),ras);
ac->Completed = ref new AsyncActionCompletedHandler(
[=] (IAsyncAction ^async_op,AsyncStatus status) mutable
{
debug->Text = L"finished";
});
where cap is a managed pointer to a MediaCapture which seems to be correctly initialized.
But the debug TextBlock never shows finished. And when I get the status of ac it seems to be blocked on Started forever, it never gets to Error or Completed. I do not understand why. So for now I implemented a dirty workaround that uses ::Windows::Media::Capture::MediaCapture::CapturePhotoToStorageFileAsync. But storing the photo in a bitmap on a file then reading it back to get the image back in memory is not satisfactory at all.
I have found a lot on taking photos with Windows Phone 8.1, but they are all in C# and copy-pasting those solutions by replacing the '.' by '::' does not work. I mean it is (at least for me) not easy at all to adapt C# code to C++ code.
So my questions are :
Is there a quick and/or clean way of getting a good old C pointer to the pixels of the image?
Why do CapturePhotoToStreamAsync block with status Started?
Thank you for your answers and your time.

Take a look at the basic camera sample app on the Microsoft Github page: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraStarterKit
There's a lot you need to do before you can take a picture (initialize, configure, start preview, etc.) and the sample will walk you through it.
Here's a shortened snippet from the sample I linked above:
/// <summary>
/// Takes a photo to a StorageFile and adds rotation metadata to it
/// </summary>
/// <returns></returns>
task<void> MainPage::TakePhotoAsync()
{
auto inputStream = ref new Streams::InMemoryRandomAccessStream();
// Take the picture
WriteLine("Taking photo...");
return create_task(_mediaCapture->CapturePhotoToStreamAsync(Windows::Media::MediaProperties::ImageEncodingProperties::CreateJpeg(), inputStream))
.then([this, inputStream]()
{
WriteLine("Photo taken!");
auto photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
return ReencodeAndSavePhotoAsync(inputStream, photoOrientation);
}).then([this](task<void> previousTask)
{
try
{
previousTask.get();
}
catch (Exception^ ex)
{
WriteException(ex);
}
});
}

Related

Qt c++ how to free memory after loading a new HTML page

I'am doing a Qt app in c++ with frontend in Html / Css.
Each time i load a new html page (or if i reload one), the app get +5mo ram, and dont get free after quit. (So after 10 pages i got +50mo ram)
I've allready try to préload my pages into a vector, but the loading still add 5mo each time.
I've also think to load pages in threads, so they'll be destroyed after using.
Is it a possible solution to keep a descent ram weight??
As i'am a newbie i'am probably doing something stupid : here's my code for loading a new view :
Q_INVOKABLE bool myBridge::newView(QString page)
{
QString path = ("file:///" + QDir::currentPath() + "/");
if (!(page.compare("page3.html")))
_mediaPlayer->setTimer(10000);
else
_mediaPlayer->setTimer(60000);
_view->close();
_view = new WebView;
_view->load(QUrl(path + page));
_view->page()->mainFrame()->addToJavaScriptWindowObject("bridge", this);
_view->showFullScreen();
_mediaPlayer->_srnsaver->timerRestart();
return (true);
}
Can you see something wrong in this code?
Every time this method is called you create a new WebView and you most likely never delete the previous one. Naturally this will cause a memory leak since nothing is freed. Calling close() does not delete the object.

Unauthorized Access Exception when Creating an instance of SpeechSynthesizer in WP8.1 Emulator

I was trying to recreate the simle Text to Speech example used on the MSDN website. However whenever the code came to create the instance of the SpeechSynthesizer class it failed with a Unauthorised Acception error when running on the WP8.1 emulator. I currently do not have an actual device to test on to see if this makes a difference.
My code was simply:
private async void TTS()
{
// The media object for controlling and playing audio.
MediaElement mediaElement = new MediaElement();
// The object for controlling the speech synthesis engine (voice).
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
// Generate the audio stream from plain text.
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
// Send the stream to the media object.
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
}
I know there was an issue with the SpeechSynthesizer in Windows 8.1, and I found solutions to this when looking to fix the problem, but found little about the problem with WP8.1 SpeechSynthesizer. Has anybody else came across this problem and found a fix?
You should add one DeviceCapability in Package.appxmanifest file:
In DeviceCapability Tab, check the microphone, because it will provides access to the microphone’s audio feed, which allows the app to record audio from connected microphones.
Look at this library: App capability declarations (Windows Runtime apps)

how to load high resolution image windows phone taskagent? [out of memory]

As we know, it is only 11.5MB memory that can be used in a Windows Phone 8 task agent. I was trying to make dynamic lock screen image in the background task agent. When I get the 480*800 image, it works fine but when I change it to 768*1280 I the exception:
Out of memory
1 pixel cast 4 K
so
(480*800*4)/1024/1024=1.46M
(768*1280*4)/1024/1024 = 3.75M
When I tried to convert a byte[] to a BitmapImage:
public BitmapImage ConvertDownloadStringToStream(byte[] downloadImageBytes)
{
if (!(downloadImageBytes.Length > 0))
return null;
RationImageInfo currentRationInfor = GetBitmapImageWidthByDeveiceRatio();
BitmapImage convertBitmapImage = new BitmapImage() { DecodePixelWidth =768, DecodePixelHeight = 1280};
using (MemoryStream imageStream = new MemoryStream(downloadImageBytes))
{
convertBitmapImage.SetSource(imageStream);//out of memory
}
return convertBitmapImage;
}
I get the out of memory exception at SetSource() method. Does anyone have suggestions about this?
I'm guessing the memory adds up.
Try saving it to a file, free the variable/resource, than load it from the file using the constructor parameter.
just try some many times i has been fix this problem.
as you see it was only have 11M memory can be use in windows phone taskagent. i was tring to make dynamic lock screen background. my soluction is download image from sever side and save to local display it.
why got out of memory Exception?
download image Byte[]=>Write to memory=>build writeableBitmap with 768*1280.
same image memory just cast three time .
so how to fix it ?
when you download your image from server side. you should be save to local isolate storage immediately and clear memory useage about the image byte[]. just set the image url to lockscreen . got be work.
download image Byte[]=>Save To local =>clear image byte memory.
everything is fine.

MvxDynamicImageHelper unreliable

I have an Mvx base iOS project which is having problems with image downloads.
I have a couple of screens which contain UICollectionViews and the UICollectionViewCells use MvxDynamicImageHelpers to set the Image of their UIImageViews to images hosted on the internet (Azure blob storage via Azure CDN in actual fact). I have noticed that the images sometimes do not appear and that this is more common on a slow connection and if I scroll through the whole UICollectionView while the images are loading - presumably as it initiates a large number of simultaneous downloads. Restarting the app causes some, but not all, of the images to be shown.
Looking in the Caches/Pictures.MvvmCross folder I see there are a number of files with .tmp extensions and some without .tmp extensions but a 0 byte file size. I presume that the .tmp files are the ones that are re-downloaded following an app restart and that an invalid in-memory cache entry is causing them not to be re-downloaded until this happens.
I have implemented my versions of MvxDownloadRequest and MvxHttpFileDownloader and registered my IMvxHttpFileDownloader. The only modification in MvxHttpFileDownloader is to use my MvxDownloadRequest instead of the standard Mvx one.
As far as I can see, there are no exceptions being thrown in MvxDownloadRequest.Start or MvxDownloadRequest.ProcessResponse and MvxDownloadRequest.FileDownloadFailed is not being called. Having replaced MvxDownloadRequest.Start with the following, all images are always downloaded and displayed successfully:
try
{
ThreadPool.QueueUserWorkItem((state) => {
try
{
var fileService = this.GetService<IMvxSimpleFileStoreService>();
var tempFilePath = DownloadPath + ".tmp";
var imageData = NSData.FromUrl(NSUrl.FromString(Url));
var image = UIImage.LoadFromData(imageData);
NSError nsError;
image.AsPNG().Save(tempFilePath, true, out nsError);
fileService.TryMove(tempFilePath, DownloadPath, true);
}
catch (Exception exception)
{
FireDownloadFailed(exception);
return;
}
FireDownloadComplete();
});
}
catch (Exception e)
{
FireDownloadFailed(e);
}
So, what could be causing the problems with the standard WebRequest which is not affecting the above version? I'm guessing it's something to with GC and will do further debugging when I get time, but this won't be fore a while unfortunately. Would be very much appreciated if someone can answer this or provide pointers for when I do look at it.
Thanks,
J
From the description of your investigations so far, it sounds like you have isolated the problem down to the level that httpwebrequest sometimes fails, but that the NSData methods are 100% reliable.
If this is the case, then it would suggest that the problem is somewhere in the xamarin.ios network stack or in the use of it.
It might be worth checking the xamarin bugzilla repository and also asking their support team if they are aware of any issues in this area. I believe they did make some announcements about changes to the iOS networking at evolve - see the CFNetworkHandler part late in the video and slides at http://xamarin.com/evolve/2013#session-b3mx6e6rmb - and there are worrying questions on here like iPhone app gets into a state where network requests never complete
Beyond that, I'd guess the first step in any debugging would be to isolate the issue in a simple test app - eg a simple app which just downloads one image at a time and which demonstrates a simple pass/fail for each technique. If you can replicate the issue in a small test app, then it'll be much quicker to work out what the issue is.

WebAPI and HTML5 SSE

was trying to encapsulate a partial view to show feedback that i can push back to the client.
This Article shows a method of pushing back data using HTML5 Server-Sent events (SSE).
I noticed that if i opened up several browser tabs and then closed one i got exceptions as the logic didn't remove the respective stream from the ConcurrentQueue. I amended the code as below
private static void TimerCallback(object state)
{
StreamWriter data;
Random randNum = new Random();
// foreach (var data in _streammessage)
for (int x = 0; x < _streammessage.Count; x++)
{
_streammessage.TryDequeue(out data);
data.WriteLine("data:" + randNum.Next(30, 100) + "\n");
try
{
data.Flush();
_streammessage.Enqueue(data);
}
catch (Exception ex)
{
// dont re-add the stream as an error ocurred presumable the client has lost connection
}
}
//To set timer with random interval
_timer.Value.Change(TimeSpan.FromMilliseconds(randNum.Next(1, 3) * 500), TimeSpan.FromMilliseconds(-1));
}
I also had to amend the OnStreamAvailable member as the framework syntax had changed to the second parameter being a HttpContent rather than HttpContentHeaders
public static void OnStreamAvailable(Stream stream, HttpContent headers, TransportContext context)
The problem now is i am still getting inconsistant behaviour if i add or remove clients i.e it times out when trying to initialise a new client. Does anyone have any ideas or more examples of using SSE with WinAPI and the correct "framework of methods" to handle disconnected clients
Cheers
Tim
This article is actually an adaptation of my original article from May - http://www.strathweb.com/2012/05/native-html5-push-notifications-with-asp-net-web-api-and-knockout-js/ (notice even variable names and port numbers are the same :-).
It is a very valid point that you are raising, and detecting a broken connection is something that's not very easy with this setup. The main reason is that while ASP.NET (the host) allows you to check a broken connection, there is no notification mechanism between ASP.NET (host) and Web API informing about that.
That is why in order to detect a broken connection (disconnected client) you should really try writing to the stream, and catch any error - this would mean the client has been disconnected.
I asked the same question to Brad Wilson/Marcin Dobosz/Damien Edwards at aspconf, and Damien suggested using HttpContext.Current.Response.IsClientConnected - so basically bypassing Web API and obtaining the connectivity info from the underlying host directly (however there is still a race condition involved anyway). That is really .NET 4. He also pointed an interesting way in which this problem could be avoided in .NET 4.5 using an async cancellation token. Frankly, I have never got around to test it, but perhaps this is something you should explore.
You can see their response to this problem in this video - http://channel9.msdn.com/Events/aspConf/aspConf/Ask-The-Experts - fast forward to 48:00