i am creating mobile application where user can post adverts with pictures and text. I am using Media.Plugin by James Montemagno. That works very well. Also the user should be able to tap on the picture to review and possibly delete. I am not sure how to access these pictures, i dont know where they are stored so even if i would want to delete them i am not sure how to access each picture. COuld you please help me?
The user is able to take several images and then they are displayed on the main page. I would like the user to be able to review them once again and then if he continues with them to the second page he will upload some other data and on the third page it should all display together. How can i Display pictures on the third page?
public partial class AddingPage : ContentPage
{
AdLogEntry adLogEntry = new AdLogEntry();
//CameraService cameraService = new CameraService();
public byte[] imageAsBytes;
public string pathLabel;
private const int MaxColumns = 3;
private int _currentRow = 0;
private int _currentColumn = 0;
public AddingPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await MainProgressBar.ProgressTo(0, 250, Easing.Linear); ;
}
private async void NextStep_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Informations());
}
private async void TakePicture_Clicked(object sender, EventArgs e)
{
await TakePicture();
}
private async Task TakePicture()
{
MediaFile file = null;
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Nemáme přístup", "Nelze nalézt kameru", "OK");
return;
}
var imageSource = await DisplayActionSheet("Foto", "Cancel", null, new string[] { "Pořídit novou fotku", "Nahrát foto z galerie" });
var photoName = Guid.NewGuid().ToString() + ".jpg";
switch (imageSource)
{
case "Pořídit novou fotku":
file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
SaveToAlbum = true,
Directory = "Photos",
Name = photoName
});
//Get the public album path
var aPpath = file.AlbumPath;
//Get private path
var path = file.Path;
break;
case "Nahrát foto z galerie":
file = await CrossMedia.Current.PickPhotoAsync();
//Directory.GetFiles( "Photos");
break;
default:
break;
}
if (file == null)
return;
// Photo => Grid
_currentColumn++;
if (_currentColumn > MaxColumns - 0)
{
_currentColumn++;
_currentRow++;
// Add a new row definition by copying the first row.
ImageGridContainer.RowDefinitions.Add(ImageGridContainer.RowDefinitions[0]);
}
var newImage = new Image()
{
Source = ImageSource.FromFile(file.Path),
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Aspect = Aspect.AspectFill,
Scale = 0
};
ImageGridContainer.Children.Add(newImage, _currentColumn, _currentRow);
await Task.Delay(250);
await newImage.ScaleTo(1, 250, Easing.SpringOut);
}
Related
I'm trying to store a model informations in my Data Base, this informations contain an image, so I created a simple view with some entrys, with a media picker button to pick it and an image witch display the picked one.
This is the button method and the store method:
async void Button_Clicked(System.Object sender, System.EventArgs e)
{
var result = await MediaPicker.PickPhotoAsync(new MediaPickerOptions
{
Title = "Please pick a photo"
});
if (result != null)
{
var stream = await result.OpenReadAsync();
resultImage.Source = ImageSource.FromStream(() => stream);
}
}
public async Task SaveMachine()
{
var machine = new Machine
{
Machine_Name = nom.Text,
Machine_Qr = qr.Text,
Files = resultImage
};
await _rest.AddMachine(machine);
await Shell.Current.GoToAsync("..");
}
But I can't create Files = resultImage because the Files in the model is in IFormFile.
I am trying to play a song from my listview in UWP. However when I click on the song (listview item) to play it I get the follwing error:
System.IO.FileNotFoundException: 'The system cannot find the file specified. (Exception from HRESULT: 0x80070002)'
This is my code:
private async Task InitFolderAsync()
{
StorageFolder musicLib = KnownFolders.MusicLibrary;
var files = await musicLib.GetFilesAsync();
foreach (var file in files)
{
StorageItemThumbnail currentThumb = await file.GetThumbnailAsync(ThumbnailMode.MusicView, 50, ThumbnailOptions.UseCurrentScale);
var albumCover = new BitmapImage();
albumCover.SetSource(currentThumb);
var musicProperties = await file.Properties.GetMusicPropertiesAsync();
var musicname = musicProperties.Title;
var musicdur = musicProperties.Duration;
var artist = musicProperties.Artist;
if (artist == "")
{
artist = "Unknown";
}
var album = musicProperties.Album;
if (album == "")
{
album = "Unknown";
}
MusicList.Add(new MusicLib
{
FileName = musicname,
Artist = artist,
Album = album,
Duration = musicdur,
AlbumCover = albumCover,
MusicPath = file.Path
});
}
}
private async void SongClicked(object sender, ItemClickEventArgs e)
{
var file = await KnownFolders.MusicLibrary.GetFileAsync(e.ClickedItem.ToString());
if (file != null)
{
var stream = await file.OpenReadAsync();
mediaElement.SetSource(stream, file.ContentType);
mediaElement.Play();
}
}
private async void objMediaPlayer_MediaEnded(object sender, RoutedEventArgs e)
{
// If the end of the ListView is reached and the last song was played stop.
if ((AudioFilesLV.SelectedIndex + 1) == AudioFilesLV.Items.Count)
{
mediaElement.Stop();
}
else
{
// This line you should try to change. When the last song was not played
//-> select next one and play them.
AudioFilesLV.SelectedIndex = AudioFilesLV.SelectedIndex + 1;
var file = await KnownFolders.MusicLibrary.GetFileAsync(AudioFilesLV.SelectedItem.ToString());
if (file != null)
{
var stream = await file.OpenReadAsync();
mediaElement.SetSource(stream, file.ContentType);
mediaElement.Play();
}
}
}
So basically after you click on the song to play it should then automatically go to the next song and play it. I haven't got to that stage yet as it does not want to play the song I clicked.
Thanks
Try to cast e.ClickedItem to a MusicLib and then pass its MusicPath to the GetFileAsync method:
private async void SongClicked(object sender, ItemClickEventArgs e)
{
var clickedItem = e.ClickedItem as MusicLib;
if (clickedItem != null)
{
var file = await KnownFolders.MusicLibrary.GetFileAsync(clickedItem.MusicPath);
if (file != null)
{
var stream = await file.OpenReadAsync();
mediaElement.SetSource(stream, file.ContentType);
mediaElement.Play();
}
}
}
I would like to take one photo at Xamarin.Forms. But when I build it, when I click on the "Take Photo" button I get the above error.
I put a breakpoint on all lines, but I could not find my fault.
Click Take Photo
ResimYukle.axml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using hackathon.CustomControls;
using hackathon.Views;
using Plugin.Media;
namespace hackathon.TabbedPages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ResimYukle : ContentPage
{
private Image img;
public ResimYukle()
{
InitializeComponent();
RelativeLayout layout = new RelativeLayout();
CustomButton btnTakePhoto = new CustomButton
{
Text = "Take Photo"
};
btnTakePhoto.Clicked += BtnTakePhoto_Clicked;
CustomButton btnPickPhoto = new CustomButton
{
Text = "Pick Photo"
};
btnPickPhoto.Clicked += BtnPickPhoto_Clicked;
CustomButton btnTakeVideo = new CustomButton
{
Text = "Take Video"
};
btnTakeVideo.Clicked += BtnTakeVideo_Clicked;
CustomButton btnPickVideo = new CustomButton
{
Text = "Pick Vİdeo"
};
btnPickVideo.Clicked += BtnPickVideo_Clicked;
StackLayout stkImage = new StackLayout
{
BackgroundColor = Color.White
};
img = new Image
{
Source = "defaultimg.png"
};
stkImage.Children.Add(img);
layout.Children.Add(stkImage, Constraint.Constant(0),
Constraint.Constant(0), Constraint.RelativeToParent(
(parent) =>
{
return parent.Width;
}));
StackLayout stkPictureButtons = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
Padding = 20,
Children =
{
btnTakePhoto,
btnPickPhoto
}
};
StackLayout stkVideoButtons = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
Padding = 20,
Children =
{
btnTakeVideo,
btnPickVideo,
}
};
layout.Children.Add(stkPictureButtons, Constraint.Constant(0),
Constraint.Constant(0), Constraint.RelativeToParent((parent) =>
{
return parent.Width;
}));
layout.Children.Add(stkVideoButtons, Constraint.Constant(0),
Constraint.RelativeToView(stkPictureButtons,
(parent, sibling) =>
{
return sibling.Height + 10;
}), Constraint.RelativeToParent((parent) =>
{
return parent.Width;
}));
Content = layout;
}
private async void BtnPickVideo_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsPickVideoSupported)
{
DisplayAlert("UYARI", "Galeriye erişme yetkiniz yok!", "OK");
return;
}
var file = await CrossMedia.Current.PickVideoAsync();
if (file == null)
return;
DisplayAlert("UYARI", "Seçilen video: " + file.Path, "OK");
file.Dispose();
}
private async void BtnTakeVideo_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
{
DisplayAlert("UYARI", "Cihazınızın kamerası aktif değil!", "OK");
return;
}
var file = await CrossMedia.Current.TakeVideoAsync(
new Plugin.Media.Abstractions.StoreVideoOptions
{
Name = DateTime.Now + ".mp4",
Directory = "MediaPluginPhotoVideo",
Quality = Plugin.Media.Abstractions.VideoQuality.High,
DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Front
});
if (file == null)
return;
DisplayAlert("UYARI",
"Video başarılı bir şekilde kayıt edildi: " + file.Path, "OK");
file.Dispose();
}
private async void BtnPickPhoto_Clicked(object sender, System.EventArgs e)
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
DisplayAlert("UYARI", "Galeriye erişme yetkiniz yok!", "OK");
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
img.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
private async void BtnTakePhoto_Clicked(object sender, System.EventArgs e)
{
int a;
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
a = 0;
int b;
DisplayAlert("UYARI", "Cihazınızın kamerası aktif değil!", "OK");
b = 0;
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(
new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "MediaPluginPhoto",
Name = DateTime.Now + ".jpg",
DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Front
});
if (file == null)
return;
img.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
}
}
ResimYukle.axml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="hackathon.TabbedPages.ResimYukle"
Title="Yükle">
</ContentPage>
I do this by looking at my example from here :
https://github.com/ozaksuty/Xamarin-Ogreniyorum/tree/master/MediaPlugin
For future reference I will take the answer of apineda in the comments and elaborate a bit.
The error here is that you have installed the NuGet package only on your shared PCL project. What you need to do is install it on your PCL project as well as your platform projects.
This is because of the way these plugins and Xamarin.Forms work. What actually happens with plugins like these is it offers you an abstract method to work with. Xamarin.Forms is targeting multi-platform, but at the end of the day, it will just transform into a native app. Because of that, it needs an implementation on the actual platform. For this example, code for showing the camera differs greatly between Android and iOS (and all other platforms for that matter).
So, effectively, you are installing the plugin on your shared library to get the method you call upon, but it is not implemented. By then installing the same plugin (but it takes another binary) to your platform project(s), the method will get it's implementation.
It is kind of hard to determine whether a plugin needs to be installed on all projects, or just the shared. Try to decide for yourself if it uses any platform specific stuff.
I have problem with getting of FolderBrowserDialog in white. I think that it should be assigned as a modal window but it isn't.
FolderBrowserDialog in DialogService.cs:
public FolderBrowserResult ShowFolderbrowserDialog(string storageFolder)
{
var dialog = new FolderBrowserDialog
{
Description = storageFolder
};
var result = new FolderBrowserResult
{
Result = dialog.ShowDialog() != DialogResult.OK,
Path = dialog.SelectedPath
};
return result;
}
Method called after click on browse button:
private void OnBrowseForTargetFolder(object sender, RoutedEventArgs e)
{
var result = dialogService.ShowFolderbrowserDialog(Properties.Resources.StorageFolder);
if (result.Result) return;
Project.PathToStorage = result.Path;
completePath = string.Format("{0}\\{1}", result.Path, Guid.NewGuid());
Directory.CreateDirectory(completePath);
}
Test:
public class LoggerTests
{
private Application application;
private MainWindowPage mainWindowPage;
[TestInitialize]
public void TestInitialize()
{
application = Application.Launch(#"PML.exe");
StartBlankApplication();
}
[TestMethod]
public void StartExistingProject()
{
mainWindowPage.StartExistingProjectButton.Click();
var modalWindows = new List<Window>();
Retry.For(() =>
{
modalWindows = mainWindowPage.applicationWindow.ModalWindows();
}, TimeSpan.FromSeconds(5));
var mod = modalWindows;
}
private MainWindowPage StartBlankApplication()
{
var appWindow = application.GetWindow("PML");
mainWindowPage = new MainWindowPage(appWindow);
return mainWindowPage;
}
private NewProjectConfigurationPage ConfigureBlankProject()
{
Window secondAppWindow = null;
Retry.For(() =>
{
secondAppWindow = application.GetWindow("PML");
}, TimeSpan.FromSeconds(5));
var newProjectConfiguration = new NewProjectConfigurationPage(secondAppWindow);
newProjectConfiguration.VesselName.Text = "Test";
newProjectConfiguration.BrowseButton.Click();
return newProjectConfiguration;
}
}
In StartExistingProject method is problem that variable mod is empty. And no FolderBrowserDialog is opened. But when I run app normally everything runs OK.
Solved - There must be setted owner to modal dialog. So
var wrapper = new WindowWrapper(this);
dialog.ShowDialog(wrapper)
solved my problem.
I am trying to write a code in which I got as xml format for the first image api from wikipedia. Now I want to parse it through c#. But I cannot get the image while running code. here is my code.
namespace WikiAPIWinForm
{
public partial class WikiForm : Form
{
private const string url1_Image1 = "https://en.wikipedia.org/w/api.php?action=query&titles=File:Schloss%20Neuschwanstein%202013.jpg&prop=imageinfo&iiprop=comment|url|dimensions&format=xml&iiurlwidth=300"; //show 1st image
private const string url1_Image2 = "https://en.wikipedia.org/w/api.php?action=query&titles=File:Neuschwanstein%20castle.jpg&prop=imageinfo&iiprop=comment|url|dimensions&format=xml&iiurlwidth=300";// show another image
private const string url1_Image3 = "https://en.wikipedia.org/w/api.php?action=query&titles=File:Hohenschwangau_-_Schloss_Neuschwanstein5.jpg&prop=imageinfo&iiprop=comment|url|dimensions&format=xml&iiurlwidth=300";// show another image
public WikiForm()
{
InitializeComponent();
}
XDocument xmlDocument1 = XDocument.Load(url1_Image1);
XDocument xmlDocument2 = XDocument.Load(url1_Image2);
XDocument xmlDocument3 = XDocument.Load(url1_Image3);
var image1 = (from page in xmlDocument1.Descendants("page")
select new AllImage
{
Title1 = page.Attribute("title").Value,
Imagerepository1 = page.Attribute("imagerepository").Value,
Url1 = page.Element("imageinfo").Element("ii").Attribute("thumburl").Value
});
ShowImages1(image1);
var image2 = (from page in xmlDocument2.Descendants("page")
select new AllImage
{
Title2 = page.Attribute("title").Value,
Imagerepository2 = page.Attribute("imagerepository").Value,
Url2 = page.Element("imageinfo").Element("ii").Attribute("thumburl").Value
});
ShowImages2(image2);
var image3 = (from page in xmlDocument3.Descendants("page")
select new AllImage
{
Title3 = page.Attribute("title").Value,
Imagerepository2 = page.Attribute("imagerepository").Value,
Url3 = page.Element("imageinfo").Element("ii").Attribute("thumburl").Value
});
ShowImages3(image3);
}
private void ShowImages1(IEnumerable<AllImage> image1)
{
var image = image1.First();
pictureLabel1.Text = image.Title1;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.LoadAsync(image.Url1);// asynchronous loading
}
private void ShowImages2(IEnumerable<AllImage> image2)
{
var image = image2.First();
pictureLabel2.Text = image.Title2;
pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox2.LoadAsync(image.Url2);// asynchronous loading
}
private void ShowImages3(IEnumerable<AllImage> image3)
{
var image = image3.First();
pictureLabel3.Text = image.Title3;
pictureBox3.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox3.LoadAsync(image.Url3);// asynchronous loading
}
}
You need something like
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false; // to prevent a new download until you have finished the old one
XDocument xmlDocument = XDocument.Load(url1_Image);
var images = (from page in xmlDocument.Descendants("page")
select new AllImage
{
Title = page.Attribute("title").Value,
Imagerepository = page.Attribute("imagerepository").Value,
Url = page.Element("imageinfo").Element("ii").Attribute("url").Value
});
ShowImages(images);
};
private void ShowImages(IEnumerable<AllImage> images)
{
var image = images.First();
label1.Text = image.Title;
pictureBox1.LoadAsync(image.Url); // asynchronous loading
}
After downloading the image you need to make the button available.
void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
button1.Enabled = true;
}
We strongly recommend to give normal names to the controls. For example, buttonLoad, labelTitle, pictureBoxWikiImage.
In addition, I see in XML information about only one image. So, for what the IEnumerable collection?