Windows Phone 7.1 -Saving path of photo taken by cameraCaputreTask - windows-phone-7

I'm building an app that should- among other things, let the user capture a picture and then save the picture and other info (like location of where this picture was taken -using GPS of the phone and etc...) on a DataBase.
Im using a string to save the pictures to the DataBase. So far so good. My problem is that after the user has captured a picture I can not find the path of the picture anyWhere (in order to display it later to the user )
I know I can display the picture if I use a image and not a string but then I am not able to save it to the DB.
Also I used the picture string (which should be the path of the picture ) to be the primaryKey column in my table and if the string is null this will be a problem for sure.
After checking on the internet I found out that you cannot use the GeoCoordinateWatcher (for GPS) on the emulator so I had to use a random place.
This led me into thinking that a picture taken by the emulator may not have a path??
Part of my code: (the Event of the camera and the bottun that saves everyting to DB)
void c_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
MessageBox.Show(e.ChosenPhoto.Length.ToString());
//Code to display the photo on the page in an image control named myImage.
BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
myImage.Source = bmp;//display the picture right after taking it. before saving to DB
p.UrlImage = bmp.UriSource.AbsolutePath;//Do not Work!
}
}
private void saveToDB_Click(object sender, RoutedEventArgs e)
{
p.Description = DesriptionList.SelectedValue.ToString();//description of the pic
p.Date = DateTime.Today;//date picture taken
GeoCoordinateWatcher myWatcher = new GeoCoordinateWatcher();
var myPosition = myWatcher.Position;
p.Location = myPosition.Location.Altitude+" "+myPosition.Location.Latitude;//do not work with emulator
p.Location = "Some Where Over The Rainbow";
MainPage.m._bl.addPic(p);//add pic to DB
MessageBox.Show("Added Successfully! :)");
NavigationService.Navigate(new Uri(#"/Intro.xaml", UriKind.Relative));//go to another page
}
}
my class:
[Table]
public class Picture
{
public Picture()
{
}
public Picture(string l, string d, string url, DateTime da)
{
Location = l;
Description = d;
UrlImage = url;
Date = da;
}
string location;
[Column]
public string Location
{
get { return location; }
set { location = value; }
}
string urlImage;
[Column (IsPrimaryKey=true)]
public string UrlImage
{
get { return urlImage; }
set { urlImage = value; }
}
DateTime date;
[Column]
public DateTime Date
{
get { return date; }
set { date = value; }
}
string description;
[Column]
public string Description
{
get { return description; }
set { description = value; }
}
}
}
Anyway- I would like to know if I can get the path in some way...
And also- if I cant get the path- does Windows have a "Better" emulator?
this emulator cant do much and this is quite annoying giving the fact I dont have a WP to check my apps on..
Thanks!

You already get the stream of the taken image in e.ChosenPhoto. You just need to save that.
var imageBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(imageBytes, 0, imageBytes.Length);
using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication()) {
using (var stream = isoFile.CreateFile("myImage.jpg")) {
stream.Write(imageBytes, 0, imageBytes.Length);
}
}
edit:
Regarding emulator, there is nothing wrong or limited about it.
The taken image is stored in a temp file that may vanish later on that's why you need to save it locally in your isolated storage if you want to display that image again.
Regarding GPS, you can use the additional tools (just click on the '>>' button on the right side of the emulator to set various settings that you find on an actual device such as accelerometer, location, network, etc.. For GeoWatcher you can define a set of points on the map that will be played back as if the device's actual GPS location was changing.

Related

Deployment of application with sound effects and txt document included

I have made an simple application which uses few sound effects and .txt document for storing some info(those files are stored into my projects bin/Debug directory).The app works fine on my PC, but when I run the .exe file on other computer, it works until the sound or .txt file is necessary(then is gives me a warning message telling that sound or .txt file isn't reachable).
How can I solve this problem, i mean, what should I do to make my app work properly on other PC's as well.Thanks!
Edit:
Here it the code which uses only sound effects(i'm changing them, so there are more than one sound)
{
public partial class GameScreen : Form
{
bool sound;
string sound1;
string sound2;
string sound3;
SoundPlayer sp1;
public GameScreen(string PlayerName)
{
InitializeComponent();
sound1 = "Air_Horn.wav";
sound2 = "TaDam.wav";
sound3 = "Bonus.wav";
sp1 = new SoundPlayer(sound1);
sound = true;
}
private void GameScreen_Load(object sender, EventArgs e)
{
if (sound == true)sp1.Play();
}
}
}
and here is the code using sound effects and .txt document:
{
public partial class VictoryForm : Form
{
SoundPlayer sp2;
string results;
bool sound_eff;
public VictoryForm(string statistics, bool _sound)
{
InitializeComponent();
sp2 = new SoundPlayer("Cheering3.wav");
results = statistics;
sound_eff = _sound;
}
private void VictoryForm_Load(object sender, EventArgs e)
{
if (sound_eff == true) sp2.Play();
}
private void VictoryForm_FormClosing(object sender, FormClosingEventArgs e)
{
StreamWriter sw = new StreamWriter("Results.txt", true);
sw.WriteLine(results);
sw.Close();
}
}
}
Sounds like you a) have not copied your texts or sound to the other computer or b) use wrong path to them. To be sure, print out the full path to the text or sound files and check if the intended files are really there. I bet they are not. ...
Btw, the contructor of StreamWriter says about its arguments: path = "The complete file path to write to", but your "Result.txt" is not a full path.

Binding Image stored in the Isolated Storage to Image Control in Windows Phone

Is it possible to bind the image present in the Isolates storage to image control through xaml. I found some implementations like getting the image through the property and binding that into xaml control. But this is not the implementation what I am searching for. My question is like, writing an attach property and helper method to fetch the content from Isolated storage. I found a similar implementation in LowProfileImage class, used in windows phone 7. But I think it is deprecated now. If anyone tried similar implementations please help me to achieve the same. Also if implementation have any performance drains please mention that info too.
Yes, it is possible to use images from isolated storage in the app UI. It requires loading the image from the file into the BitmapImage and then binding ImageSource of your control to that BitmapImage. I'm using the following approach:
First, there's a method to load image asynchronously:
private Task<Stream> LoadImageAsync(string filename)
{
return Task.Factory.StartNew<Stream>(() =>
{
if (filename == null)
{
throw new ArgumentException("one of parameters is null");
}
Stream stream = null;
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStore.FileExists(filename))
{
stream = isoStore.OpenFile(filename, System.IO.FileMode.Open, FileAccess.Read);
}
}
return stream;
});
}
Then it can be used like this:
public async Task<BitmapSource> FetchImage()
{
BitmapImage image = null;
using (var imageStream = await LoadImageAsync(doc.ImagePath))
{
if (imageStream != null)
{
image = new BitmapImage();
image.SetSource(imageStream);
}
}
return image;
}
And finally you just assign return value of FetchImage() method to some of your view model's property, to which the UI element is bound. Of course, your view model should properly implement INotifyPropertyChanged interface for this approach to work reliably.
If you want to use attached properties approach, here's how you do it:
public class IsoStoreImageSource : DependencyObject
{
public static void SetIsoStoreFileName(UIElement element, string value)
{
element.SetValue(IsoStoreFileNameProperty, value);
}
public static string GetIsoStoreFileName(UIElement element)
{
return (string)element.GetValue(IsoStoreFileNameProperty);
}
// Using a DependencyProperty as the backing store for IsoStoreFileName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsoStoreFileNameProperty =
DependencyProperty.RegisterAttached("IsoStoreFileName", typeof(string), typeof(IsoStoreImageSource), new PropertyMetadata("", Changed));
private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Image img = d as Image;
if (img != null)
{
var path = e.NewValue as string;
SynchronizationContext uiThread = SynchronizationContext.Current;
Task.Factory.StartNew(() =>
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStore.FileExists(path))
{
var stream = isoStore.OpenFile(path, System.IO.FileMode.Open, FileAccess.Read);
uiThread.Post(_ =>
{
var _img = new BitmapImage();
_img.SetSource(stream);
img.Source = _img;
}, null);
}
}
});
}
}
}
And then in XAML:
<Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" />
Some limitations of this approach:
It only works on Image control, though you can change this to a whichever type you want. It's just not very generic.
Performance-wise, it will use a thread from the threadpool every time image source is changed. It's the only way to do asynchronous read from isolated storage on Windows Phone 8 right now. And you definitely don't want to do this synchronously.
But it has one one important advantage:
It works! :)
I like the above approach but there is a simpler more hacky way of doing it if you are interested.
You can go into your xaml and bind the image source to an string property then put the file path into the property dynamically.
<!-- XAML CODE -->
<Image Source="{Binding imagePath}"/>
//Behind property
public String imagePath { get; set; }
load your path into the image path then bind the image source to the image path string. You might have to do an INotifyPropertyChanged but this method should work with proper binding.

Emulators Providing Different Results

I am developing an application on windows phone with version 7.1 set as my target build. The problem i am having is that one of the listviews in on of my pages refus to display.
I have debugged to ensure the list gets parsed with contents inside of it . Also the application runs fine when i use a windows 8 emulator. But the same technique used in populating other listviews in other pages of the application work fine on all emulators aprt from this single page that does not display.
I even tried to set the colour of the binding stack panel to see if it will show up and it does but without any content.
I am really confused and my code is very perfect. I wonder if any one has seem this issue before with windows phone emulators?
private void countdownClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
HtmlDocument doc = new HtmlDocument();
if (e.Error != null)
{
//MessageBox.Show(e.Error.InnerException.Message + "\n Ensure You Have A Working Internet Connection");
return;
}
doc.LoadHtml(e.Result);
String noCountdown = "<div><span>Sorry no buses are expected within 30 minutes of this stop. Please try again later or go to www.tfl.gov.uk</span></div>";
if (e.Result.Contains(noCountdown))
{
//No Buses Expected;
return;
}
else
{
HtmlNode stopCountdownNode;
try
{
stopCountdownNode = doc.DocumentNode.SelectSingleNode("//*[contains(#id, 'stopBoard')]").SelectSingleNode("tbody");
}
catch (Exception)
{
MessageBox.Show("Error Responce From Server");
return;
}
if (stopCountdownNode != null)
{
HtmlNodeCollection countdownNodeList = stopCountdownNode.SelectNodes("tr");
CountDownListBox.ItemsSource = GetCountdownList(countdownNodeList);
}
}
}
private ObservableCollection<BusCountdown> GetCountdownList(HtmlNodeCollection countdownNodeList)
{
ObservableCollection<BusCountdown> countdownList = new ObservableCollection<BusCountdown>();
foreach (HtmlNode countDown in countdownNodeList)
{
String busName = HttpUtility.HtmlDecode(countDown.SelectSingleNode("*[contains(#class, 'resRoute')]").InnerHtml);
String busDestination = HttpUtility.HtmlDecode(countDown.SelectSingleNode("*[contains(#class, 'resDir')]").InnerHtml);
String countDownTime = HttpUtility.HtmlDecode(countDown.SelectSingleNode("*[contains(#class, 'resDue')]").InnerHtml);
countdownList.Add(new BusCountdown(busName, busDestination, countDownTime));
}
return countdownList;
}
public string GetRandomSlash()
{
Random r = new Random();
String slash = "";
int rand = r.Next(1, 20);
for (int i = 0; i < rand; i++)
{
slash += "/";
}
return slash;
}
Try setting your class access specifier which you use to bind to public and give it a try. Let me know if it works.
For ex:
public class Bindingclass
{
public string Name{get;set;}
}
Try using Expression Blend and also delete your previous solution file and build a new solution.
Also set the build action property properly for all pages.
Update your SDK to 7.8 version. You will get multiple choices for Emulators - Emulator 7.1 (256 MB), Emulator 7.1 (512 MB), Emulator 7.8 (256 MB), Emulator 7.8 (512 MB). Test it on all these versions and check output on each Emulator type.
I hope at least one of these helps you get things get working. Let us know.

Adding custom metadata tags using LibTiff.Net

I now how to add a custom tag to an image but it's not showing up as the tag name in image viewer. I only see the number I assigned and its value.
Why there is no proper name for my custom tag?
using BitMiracle.LibTiff.Classic;
namespace WindowsFormsApplication1
{
class Program
{
private const TiffTag IMG_GUID = (TiffTag)666;
private static Tiff.TiffExtendProc m_parentExtender;
public static void TagExtender(Tiff tif)
{
TiffFieldInfo[] tiffFieldInfo =
{
new TiffFieldInfo(IMG_GUID, -1, -1, TiffType.ASCII, FieldBit.Custom, true, false, "IMG_GUID"),
};
tif.MergeFieldInfo(tiffFieldInfo, tiffFieldInfo.Length);
if (m_parentExtender != null)
m_parentExtender(tif);
}
static void Main(string[] args)
{
// Register the extender callback
// It's a good idea to keep track of the previous tag extender (if any) so that we can call it
// from our extender allowing a chain of customizations to take effect.
m_parentExtender = Tiff.SetTagExtender(TagExtender);
byte[] buffer = new byte[25 * 144];
string outputFileName = writeTiffWithCustomTags(buffer);
// restore previous tag extender
Tiff.SetTagExtender(m_parentExtender);
}
private static string writeTiffWithCustomTags(byte[] buffer)
{
string existingTiffName = "..\\..\\tifimages\\cramps.tif";
string outputFileName = existingTiffName;
using (Tiff image = Tiff.Open(outputFileName, "a"))
{
// set custom tags
image.SetDirectory(0);
string value = "test";
image.SetField(IMG_GUID, value);
image.CheckpointDirectory();
// Write the information to the file
image.WriteEncodedStrip(0, buffer, 25 * 144);
}
return outputFileName;
}
}
}
The application you use for viewing your TIFFs should know about your custom tags beforehand in order to be able to display its names.
It's not gonna happen! (Because you may select almost arbitrary integer for your custom tag).
So, there is nothing wrong with custom tags being displayed as (an integer, a value) pair. It's just the way custom tag work.

String as a GeoCoordinate

I am developing an application which is storing places in database.
The problem is:
I have a main view of map, then I click add place button. The button goes to standard form which contains name, description and coordinates. Coordinates I am taking from map and changing to string. Then it saves in SQLite database.
But I have no idea how use geocoordinates from DB, because they are strings, not a GeoCoordinates, and simply I can't use them to for example pushpin with binding data
Considering there is no GeoCoordinate.Parse() method and assuming your string representation comes from GeoCoordinate.ToString(), you could use something like this:
public GeoCoordinate ParseGeoCoordinate(string input)
{
if (String.IsNullOrEmpty(input))
{
throw new ArgumentException("input");
}
if (input == "Unknown")
{
return GeoCoordinate.Unknown;
}
// GeoCoordinate.ToString() uses InvariantCulture, so the doubles will use '.'
// for decimal placement, even in european environments
string[] parts = input.Split(',');
if (parts.Length != 2)
{
throw new ArgumentException("Invalid format");
}
double latitude = Double.Parse(parts[0], CultureInfo.InvariantCulture);
double longitude = Double.Parse(parts[1], CultureInfo.InvariantCulture);
return new GeoCoordinate(latitude, longitude);
}

Resources