I am working on (what should have been) a very simple project. It needs to
(1). Allow a user to select an image file then convert this into a format that can be stored in a database as a BLOB.
(2). Output the BLOB data into a textbox.
(3). The text that is output in the box needs to be capable of being stored into a database and then successfully converted back into an image (this conversion is handled elsewhere_.
This application here is just supposed to do the initial conversion (image to BLOB) so that the user can insert the image into an SQL database. However, whenever I run the program, it 'freezes' whenever I try opening the file. What am I doing wrong? Is there a more efficient approach to accomplish what I am trying to do?
Thanks much!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows.Forms;
using System.IO;
namespace Binary_Converter
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private OpenFileDialog imageDialog = new OpenFileDialog();
private FileStream imageStream;
public MainWindow()
{
InitializeComponent();
imageDialog.InitialDirectory = "c://";
imageDialog.Filter = "Image Files | *.jpg; *.gif; *.png";
imageDialog.FileOk += imageDialog_FileOk;
}
private void UI_Loaded(object sender, RoutedEventArgs e)
{}
void imageDialog_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
if((imageStream = (FileStream)imageDialog.OpenFile()) != null) {
byte[] buffer;
using(imageStream) {
buffer = new byte[imageStream.Length];
imageStream.Read(buffer, 0, (int)imageStream.Length);
}
foreach(byte i in buffer) {
outputText.Text += buffer[i];
}
}
}
private void addFileButton_Click(object sender, RoutedEventArgs e)
{
imageDialog.ShowDialog();
}
}
}
I think that your program freezes because you haven't converted the values to hexadecimal format. You are trying to output raw byte values, and it will "harm" your textbox as it will interpret it as a string with control characters. Hexadecimal format will be needed if you want to insert the value into the database.
foreach(byte i in buffer) {
outputText.Text += buffer[i];
}
outputText.Text = "0x"; // begin the string with 0x to tell that it is hexadecimal
foreach(byte i in buffer) {
outputText.Text += buffer[i].ToString("x2"); // convert each byte to hexadecimal form
}
You don't need to pass it to a textbox and then save it to the database.
If you have an Image or Blob column you save the byte[] directly.
This article (http://www.codeproject.com/Articles/33310/C-Save-and-Load-Image-from-Database) has more information about this.
Related
I am testing a small app where main window has a text box for entry, user clicks add (List Add in code) and it updates a simple list. In addition to the list update a dynamic button will be created in a wrap panel. The idea is the user then can click what ever entry they need to update and it load the second window with that entry correlated to an index in the list.
I have code that works for the most part but am blanking on what I believe is something trivial. If there is 3 buttons created and I go to click button 3 it will pop up all entries. So three windows with their assigned index. I just need the one window to show for the button that was clicked. I have played around and this particular issue is escaping me.
I have searched for a similar answer but came up short over the past few days.
MainWindow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TestApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
List<string> listA = new List<string>();
private int x = 1;
private int t = 1;
private void addBtn_Click(object sender, RoutedEventArgs e)
{
listA.Add(listBx.Text);
Button btns = new Button();
btns.Width = 70;
btns.Height = 30;
btns.Content = "Button " + x;
btns.Name = "Btn" + t;
btns.Click += (s, t) =>
{
for (int index = 0; index < listA.Count; index++)
{
EditWindow win = new EditWindow();
win.updateBx.Text = listA[index];
win.Show();
}
};
btnPanel.Children.Add(btns);
x++;
t++;
}
}
}
Second window (no code here yet, update btn will rewrite list index it correlates with:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace TestApp
{
/// <summary>
/// Interaction logic for EditWindow.xaml
/// </summary>
public partial class EditWindow : Window
{
public EditWindow()
{
InitializeComponent();
}
private void updateBtn_Click(object sender, RoutedEventArgs e)
{
}
}
}
I am not familiar with c# but the reason is i guess the loop in the click function. It does what you said. Instead of loop you should only use the current listA element.
In your button event handler, you are using a for loop to open an EditWindow for every entry in the list. Instead, only open one EditWindow and populate it with the specified entry.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Ozeki.Camera;
using Ozeki.Media;
using Ozeki;
using System.Windows.Media;
namespace BasicCameraViewer
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private VideoViewerWPF _videoViewerWPF;
private BitmapSourceProvider _provider;
private IIPCamera _ipCamera;
private WebCamera _webCamera;
private MediaConnector _connector;
public MainWindow()
{
InitializeComponent();
_connector = new MediaConnector();
_provider = new BitmapSourceProvider();
SetVideoViewer();
}
private void SetVideoViewer()
{
_videoViewerWPF = new VideoViewerWPF
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Background= Brushes.Black
};
CameraBox.Children.Add(_videoViewerWPF);
_videoViewerWPF.SetImageProvider(_provider);
}
#region IP Camera Connect/Disconnect
private void ConnectIPCamera_Click(object sender, RoutedEventArgs e)
{
var host = HostTextBox.Text;
var user = userTextBox.Text;
var pass = Password.Password;
_ipCamera = IPCameraFactory.GetCamera(host, user, pass);
if (_ipCamera == null) return;
_connector.Connect(_ipCamera.VideoChannel, _provider);
_ipCamera.Start();
_videoViewerWPF.Start();
}
private void DiconnectIPCamera_Click(object sender, RoutedEventArgs e)
{
_videoViewerWPF.Stop();
_ipCamera.Disconnect();
_ipCamera.Dispose();
_connector.Disconnect(_ipCamera.VideoChannel, _provider);
}
#endregion
}
}
Can somebody tell me what I could do? It tells me that i can not convert the _videoViewerWPF.SetImageProvider(_provider) line from Ozeki.Media.BitmapSourceProvider to Ozeki.Media.IImageProvider and i have absolutely no idea what to do that it could work.
I tried several times to do something, but I dont even know what I´m doing.
I would be thankfull if somebody could help me so I can finish this.
I came across the same issue after following the Ozeki video C# camera tutorial #3 - Camera viewer on YouTube.
It may be that the API has moved on since that video because sample code on the Ozeki Website (How to connect to an RTSP camera and display the picture in C#) uses a DrawingImageProvider instead of a BitmapSourceProvider:
...
private DrawingImageProvider _provider = new DrawingImageProvider();
...
...and then (for a WPF app):
_videoViewerWpf.SetImageProvider(_provider);
In my case, this fixed the compiler error and I can now display RTSP video in a WPF app.
I'm creating a little WPF app in VS2013Express and I've come across a little problem.
You see, there are three windows, MainWindow, LatAndLongDialog, TimeCitiesDialog.
`LatAndLongDialog` and `TimeCitiesDialog` are opened from MainWindow (with the click of a button).
I want all the other windows to close when the `Closed()` event is called on `MainWindow`.
The code on MainWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace GlobalTime_ELITE_for_WPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
UserDescText.Content =
"Select a TimeCity or enter the latitude and longitude in \n" +
"to view the World Time there. Or, select another one of the\n" +
"options below to do that. Go to Help by clicking on the link\n" +
"on the upper-right corner of the window to view everything you\n" +
"can do.";
this.Closed += CloseOff;
}
private void OpenTimeCitiesDialog(Object Sender, EventArgs E)
{
TimeCitiesDialog ObjectReference = new TimeCitiesDialog();
ObjectReference.Show();
}
private void OpenLatAndLongDialog(Object Sender, EventArgs E)
{
LatAndLongDialog ObjectReference = new LatAndLongDialog();
ObjectReference.Show();
}
private void CloseOff(Object Sender, EventArgs E)
{
this.Close();
TimeCitiesDialog tcdor = new TimeCitiesDialog();
LatAndLongDialog laldor = new LatAndLongDialog();
}
}
}
How can I close them all? Please help!
The proper way to shutdown a WPF app is to use Application.Current.Shutdown() . This will close all open Windows, raise some events so that cleanup code can be run, and it can't be canceled.
Environment.Exit() terminates the application immediately even if other threads are executing.
You should also consider setting the Owner on non-main Windows. The behavior will likely be more like what you would expect in regards to Z-order, minimizing, and maximizing. As an added bonus, the owned windows will automatically close when the owner Window closes.
private void CloseAllWindows()
{
for (int intCounter = App.Current.Windows.Count - 1; intCounter >= 0; intCounter--)
{
App.Current.Windows[intCounter].Close();
}
}
Close all opened current windows.
Use this instead this.Close()
Environment.Exit(0);
this will force everything to close
If you keep track of the Dialogs outside of the scope of the methods you use to open them, you can call which ever methods on those Dialogs you wish from anywhere within the Class. Here I have them as Class variables and they are instantiated there but not shown until you press the buttons. You can also create "Close" buttons for those specific windows and call their .Close() methods when ever you wish. That will allow you to open and close them at will. You can also call their .Close() methods when the main form closes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace GlobalTime_ELITE_for_WPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
TimeCitiesDialog tcDialog = new TimeCitiesDialog();
LatAndLongDialog lalDialog = new LatAndLongDialog();
public MainWindow()
{
InitializeComponent();
UserDescText.Content = "Select a TimeCity or enter the latitude and longitude in \n" +
"to view the World Time there. Or, select another one of the\n" +
"options below to do that. Go to Help by clicking on the link\n" +
"on the upper-right corner of the window to view everything you\n" +
"can do.";
this.Closed += CloseOff;
}
private void OpenTimeCitiesDialog(Object Sender, EventArgs E)
{
tcDialog.Show();
}
private void OpenLatAndLongDialog(Object Sender, EventArgs E)
{
lalDialog.Show();
}
private void CloseOff(Object Sender, EventArgs E)
{
// Close the dialogs first, then allow this method
// to end which will finish the this.Close() process.
tcDialog.Close();
lalDialog.Close();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Web;
using System.IO;
namespace WpfApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public MainWindow(Stream stream)
{
InitializeComponent();
String path = #"C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg";
var image = new BitmapImage();
try
{
image.BeginInit();
image.StreamSource = stream;
image.EndInit();
using (Stream bmpStream = System.IO.File.Open(path,System.IO.FileMode.Open))
{
Image im = Image.FromStream(bmpStream);
//Bitmap img = (Bitmap)Image.FromFile("aa.gif", true);
//var im = ImageFromStream(bmpStream);
grid1.Background = new ImageBrush(new BitmapImage(new Uri(#"im")));
}
// return image;
}
catch (Exception a)
{
// return image;
}
}
public void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
I am using the above code to stream the jpg image as bitmap, and set it into a grid using c#, but Image im = Image.FromStream(bmpStream); shows an error. Can someone please guide me in how to stream the jpg image as bitmap and set into grid?
The way WPF handles and displays images is a bit different from the way WinForms did this.
Most image-displaying "things" need a ImageSource and you have to search for the right one to use.
In this case you should be able to use the BitmapImage - but the last time I checked this one needs some more care to display the content of a byte-stream correctly.
This snippet shows how you should be able to get this working right BitmapImage:
private static BitmapImage LoadImage(Stream stream)
{
// assumes that the streams position is at the beginning
// for example if you use a memory stream you might need to point it to 0 first
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
image.Freeze();
return image;
}
As you can see you need to tell the image to use the stream as soon as it loads (or you can get nasty things like ObjectDisposedExceptions.
You can use the returned object as your Image's source property.
So I think what you are looking for is something like this:
public MainWindow(Stream stream)
{
InitializeComponent();
grid1.Background = new ImageBrush(LoadImage(stream));
}
I've made a simple program (closely resting on this example) that visualises my problem. It only downloads a file from specified URL, nothing more; everything was OK until I tried with such data:
http://www.youtube.com/watch?v=pqaARDsiJv4
Surprisingly, nothing happens. Why it doesn't download neither the related video nor the HTML source code?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.IO;
using System.ComponentModel;
namespace downloader
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void DownloadButton_Click(object sender, RoutedEventArgs e)
{
WebClient client = new WebClient();
string fileName;
try
{
fileName = System.IO.Path.GetFileName(URLBox.Text);
Uri currentURL = new Uri(URLBox.Text);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
client.DownloadFileAsync(currentURL, fileName);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
progressBar.Value = 0;
}
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Download Completed!");
}
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
}
}
For such an URL this line...
fileName = System.IO.Path.GetFileName(URLBox.Text);
...sets fileName to "watch?v=pqaARDsiJv4", which is not a legal file name.
I don't think that you can download a video from Youtube like that. I will refer you to a Stack Exchange question from last year regarding downloading content from Youtube; there are many links and even a method for doing it. But all of these solutions are 3 years old, they may no longer work now; that's part of the problem with what you want to do; Google is constantly making changes, which will most likely break any current solutions.
You can see if any of the solutions provided here still work: https://stackoverflow.com/questions/1852029/how-can-i-download-youtube-videos-using-net-code
Or use the information provided to create your own.