Refactor code - make class [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I want to make a class Photo where can I submit methods, because I will be use these methods many times in many pages.
So how can I send my image in parameter ?
Now I have :
PhotoChooserTask selectPhoto = null;
private void chooseLogoButton_Click(object sender, RoutedEventArgs e)
{
selectPhoto = new PhotoChooserTask();
selectPhoto.Completed += new EventHandler<PhotoResult>(selectPhoto_Completed);
selectPhoto.Show();
}
void selectPhoto_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.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
logoQrCodeImage.Source = bmp;
}
}
And I made a class Photo:
public class Photo
{
PhotoChooserTask selectPhoto = null;
public void chooseLogo()
{
selectPhoto = new PhotoChooserTask();
selectPhoto.Completed += new EventHandler<PhotoResult>(selectPhoto_Completed);
selectPhoto.Show();
}
void selectPhoto_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.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
logoQrCodeImage.Source = bmp; //ERROR
}
}
}

You could build your class to support Tasks and then use an async/await event handler. So your class would look like this:
public class PhotoChooser
{
public Task<BitmapImage> ChoosePhoto()
{
var taskSource = new TaskCompletionSource<BitmapImage>();
var chooser = new PhotoChooserTask();
chooser.Completed += (s, e) =>
{
if (e.ChosenPhoto == null)
{
taskSource.SetResult(null);
}
else
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
taskSource.SetResult(bmp);
}
};
chooser.Show();
return taskSource.Task;
}
}
The your event handler would look like this:
private async void ChoosePhoto_OnClick(object sender, RoutedEventArgs e)
{
var chooser = new PhotoChooser();
logoQrCodeImage.Source = await chooser.ChoosePhoto();
}
Update:
If you are using Windows Phone 7 you can still use async and await by adding the Async for Silverlight, .NET 4, Windows Phone NuGet Package. Just add a nuget reference and search for Async. It should be the first one.

You can supply a callback on what to do when the photo finishes selecting.
For example, you can add event to Photo class (you'd need to define class PhotoEventHandler too)
public class PhotoEventArgs
{
public Bitmap Bmp;
}
public event EventHandler<PhotoEventArgs> photoSelectCompleted;
and in the method invoke the event
void selectPhoto_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.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
if (photoSelectCompleted != null)
photoSelectCompleted(this, new PhotoEventArgs(){ Bmp = bmp;});
}
}
and in the original page subscribe to the event and in the eventhandler do this:
void photoSelectCompleted(object sender, PhotoEventArgs e)
{
logoQrCodeImage.Source = e.Bmp;
}

Related

Load an Image to a Canvas Control from a File Picker

What I'm trying to do in a UWP app with Win2D:
User pressed a button to add an image and picks their file.
That file gets loaded as a resource for a Canvas Control.
The image then gets rendered to the current drawing session
When the button is clicked:
private async void btnAddPicture_Click(object sender, RoutedEventArgs e)
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
overlayPictureFile = await picker.PickSingleFileAsync();
if (overlayPictureFile == null)
{
txbNotification.Text = "File Picking cancelled";
return;
}
else
{
txbNotification.Text = "Picture Loaded";
}
using (IRandomAccessStream stream = await overlayPictureFile.OpenAsync(FileAccessMode.Read))
{
var device = new CanvasDevice();
createdBitmap = await CanvasBitmap.LoadAsync(device, stream);
}
}
In the drawing function:
void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
if (createdBitmap != null)
{
args.DrawingSession.DrawImage(createdBitmap, Drawing.FindDefaultRect());
}
drawingCanvas.Invalidate();
}
Everything will compile but the moment I press the button to add an image it breaks here.
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
I'm already loading some image in this, but those are all part of the program and are created before the canvas is created with these. Not sure how to do that with ones the user picks.
private void drawingCanvas_CreateResources(CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
}
private async Task CreateResourcesAsync(CanvasControl sender)
{
logo = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///Assets/Pictures/Logo_BlackBorders.png"));
}
Update:
Where I currently am drawing things. This is the canvas I'm trying to add the image to.
void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
//Drawing a bunch of stuff
}
private void drawingCanvas_CreateResources(CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
}
private async Task CreateResourcesAsync(CanvasControl sender)
{
logo = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///Assets/Pictures/Logo.png"));
}
Load an Image to a Canvas Control from a File Picker
For your scenario, you could get CanvasDrawingSession with CreateDrawingSession method. And then use this drawingsession to draw picked image to current CanvasControl.
For example.
private async void btnAddPicture_Click(object sender, RoutedEventArgs e)
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
var overlayPictureFile = await picker.PickSingleFileAsync();
if (overlayPictureFile == null)
{
return;
}
else
{
}
using (IRandomAccessStream stream = await overlayPictureFile.OpenAsync(FileAccessMode.Read))
{
//get canvascontrol's Device property.
CanvasDevice device = drawingCanvas.Device;
createdBitmap = await CanvasBitmap.LoadAsync(device, stream);
//use device property to make renderer
var renderer = new CanvasRenderTarget(device,
createdBitmap.SizeInPixels.Width,
createdBitmap.SizeInPixels.Height, createdBitmap.Dpi);
//make ds with above renderer.
using (var ds = renderer.CreateDrawingSession())
{
ds.DrawImage(createdBitmap, 0, 0);
}
}
}

How to Insert bitmap image to sqlite database on Windows phone 8.1 c#

I have managed to pick an image from the phones library and display it. this is the code. Question is how do i Insert this image into my Sqlite database of contacts and retrieve it and display it again after getting the image? Here is my code. A detailed step by step instruction would be appreciated from here.
namespace Mobile_Life.Pages
{
public sealed partial class NextOFKin_Update_Delete : Page
{
int Selected_ContactId = 0;
DatabaseHelperClass Db_Helper = new DatabaseHelperClass();
Contacts currentcontact = new Contacts();
CoreApplicationView view;
public NextOFKin_Update_Delete()
{
this.InitializeComponent();
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
view = CoreApplication.GetCurrentView();
}
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
if (Frame.CanGoBack)
{
e.Handled = true;
Frame.GoBack();
}
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
await StatusBar.GetForCurrentView().ShowAsync();
Selected_ContactId = int.Parse(e.Parameter.ToString());
currentcontact = Db_Helper.ReadContact(Selected_ContactId);//Read selected DB contact
namestxt.Text = currentcontact.Name;//get contact Name
relationtxt.Text = currentcontact.Relation;//get contact relation
phonetxt.Text = currentcontact.PhoneNumber;//get contact PhoneNumber
}
private void Update_click(object sender, RoutedEventArgs e)
{
currentcontact.Name = namestxt.Text;
currentcontact.Relation = relationtxt.Text;
currentcontact.PhoneNumber = phonetxt.Text;
Db_Helper.UpdateContact(currentcontact);//Update selected DB contact Id
Frame.Navigate(typeof(NextOfKin));
}
private void Delete_click(object sender, RoutedEventArgs e)
{
Db_Helper.DeleteContact(Selected_ContactId);//Delete selected DB contact Id.
Frame.Navigate(typeof(NextOfKin));
}
private void profile_img(object sender, TappedRoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
filePicker.FileTypeFilter.Clear();
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.PickSingleFileAndContinue();
view.Activated += viewActivated;
}
private async void viewActivated(CoreApplicationView sender, IActivatedEventArgs args1)
{
FileOpenPickerContinuationEventArgs args = args1 as FileOpenPickerContinuationEventArgs;
if (args != null)
{
if (args.Files.Count == 0) return;
view.Activated -= viewActivated;
StorageFile storageFile = args.Files[0];
var stream = await storageFile.OpenAsync(FileAccessMode.Read);
var bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
profile.ImageSource = bitmapImage;
}
}
}
The best way would be NOT to store the image in SQLite. Just copy it to your ApplicationData.Current.LocalFolder and save the path.
If you really want to store the BitmapImage in SQLite, just convert it to byte array: Convert a bitmapimage to byte[] array for storage in sqlite database

Capture images from webcam in c# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I've been working on an application which generates and reads(decode) QR codes. In decoding part the user capture the picture of QR code and the program will start process of decoding.
My problem is I don't Know how I can take the photo.
P.S:
If you offer a library please give a link which contains the tutorial of using that lib.
Thank you.
I have been looking for web cam recording since a long time, you can use Aforge.NET .
Here is code for the same using WPF :
public partial class MainWindow : Window
{
private FilterInfoCollection VideoCaptureDevices;
private VideoCaptureDevice FinalVideo;
public VideoFileWriter writer= new VideoFileWriter();
public MainWindow()
{
InitializeComponent();
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo VideoCaptureDevice in VideoCaptureDevices)
{
comboBox1.Items.Add(VideoCaptureDevice.Name);
}
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
writer.Open(#"d:\\newVid.avi", 640, 480, 25, VideoCodec.MPEG4);
FinalVideo = new VideoCaptureDevice(VideoCaptureDevices[comboBox1.SelectedIndex].MonikerString);
FinalVideo.NewFrame += new NewFrameEventHandler(FinalVideo_NewFrame);
FinalVideo.Start();
}
void FinalVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
System.Drawing.Image imgforms = (Bitmap)eventArgs.Frame.Clone();
Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
imgforms.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
//Using the freeze function to avoid cross thread operations
bi.Freeze();
//Calling the UI thread using the Dispatcher to update the 'Image' WPF control
Dispatcher.BeginInvoke(new ThreadStart(delegate
{
pictureBox1.Source = bi; /*frameholder is the name of the 'Image' WPF control*/
}));
for (int i = 0; i < 2; i++)
{
writer.WriteVideoFrame(bmp);
}
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
writer.Close();
FinalVideo.Stop();
this.Close();
}
}
include below namespaces:
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using System.Drawing.Drawing2D;
using AForge.Video.VFW;
You can set change frame rate as per your convenience.

PhotoChooserTask how to pass extra parameter Windows Phone

Say I have this code
private void photoChooserBtn_Click(object sender, RoutedEventArgs e)
{
photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult (photoChooserTask_Completed);
photoChooserTask.Show();
}
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
imagecontrol.Source = bmp;
}
}
I have to repeat this code several times as I have several buttons. I want to avoid this.
I want to have one button click event. Then append extra parameter to photoChooserTask so that I can process the result in photoChooserTask_Completed event based on the parameter.
So in photoChooserBtn_Click event. I would like to do something like this.
Button btn = (Button)sender;
photoChooserTask.Tag = btn.Name;
Then
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
imagecontrol.Source = bmp;
string param = ((PhotoChooserTask)sender).Tag;
Switch (param)
{
case "bla":
case "bla2":
...........
}
}
What's the best way to do this?
What you are looking for is not possible. However you can add a string tag property to your page. Since only one PhotoChooserTask can run at a time, this approach should be fine.
public partial class MainPage : PhoneApplicationPage
{
string tag;
// Constructor
public MainPage()
{
InitializeComponent();
}
private void photoChooserBtn_Click(object sender, RoutedEventArgs e)
{
photoChooserTask = new PhotoChooserTask();
tag = (sender as Button).Name;
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
photoChooserTask.Show();
}
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
imagecontrol.Source = bmp;
switch(tag)
{
case tag1:
case tag2:
........
}
tag = null;
}
}

C# Passing image on select from one page to another xaml page in WindowsPhone

Using Photochooser Task the image has to be loaded and passed immediately to another page. But shows blank when implemented the following code:
private void LoadPicture_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask photoChooserTask;
photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
photoChooserTask.Show();
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
}
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
Page1 p1 = new Page1();
p1.encodeImg.Source = bmp;
}
else
{
MessageBox.Show("Image Loading Failed.");
}
}
Please suggest in fixing the above the issue.
Thanks!
Have you solved it? if you haven't you could use something like this. in your photoChooseTask handler save the bitmapImage
PhoneApplicationService.Current.State["yourparam"] = bmp;
and then in your Page1 you get the bitmapImage
BitmapImage bitmapGet = PhoneApplicationService.Current.State["yourparam"] as BitmapImage;
here's how you should use this.
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
//save the bitmapImage
PhoneApplicationService.Current.State["yourparam"] = bmp;
}
else
{
MessageBox.Show("Image Loading Failed.");
}
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
}
your Page1
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
//get the bitmapImage
BitmapImage bitmapGet = PhoneApplicationService.Current.State["yourparam"] as BitmapImage;
//set the bitmpaImage
img.Source = bitmapGet;
base.OnNavigatedTo(e);
}
More about PhoneApplicationService.Current.State :)
The navigation must be done after completed event, photochooser.show() suppresses the main application thread, hence you can only pass the image stream once you get it. So, shift navigation statement to completed event handler and using isolatedstoragesettings.applicationsettings to store the image and get it back on second page.
Another way to achieve it is to save the image in isolateStorage first and pass the file path to your page1 as a string parameter.
page1 then could load the image anytime it needs.

Categories