I'm creating BitmapImages, to download images from IP cam.
I use DownloadCompleted, DownloadFailed and DownloadProgress events.
But every hour, I reset everything. Those images are created dynamically, and I'd like to clear them (or destroy them) when I reset. But I don't find them, and they continue to fire the events....
Here the example :
void dispatcherTimer_Tick(object sender, EventArgs e)
{
BitmapImage img = New BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.None;
img.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
img.DownloadCompleted += DownloadCompleted;
img.DownloadFailed += DownloadFailed;
img.DownloadProgress += bi_DownloadProgress;
img.UriSource = new Uri(xR["URLJPG"].ToString());
//xR["URLJPG"] is a DataViewRow, that contains the url to download for each image)
img.EndInit();
}
There is several images created this way. I'd like to clear ou destroy them all.
Related
So i have this code which for every string in the array it adds it the file path and uses it as the file path for the image box, this is the code:
private async void Button7_Click(object sender, RoutedEventArgs e)
{
string[] images = new string[] { "Star_00001.png", "Star_00002.png", "Star_00003.png", "Star_00004.png", "Star_00005.png", "Star_00006.png", "Star_00007.png", "Star_00008.png"};
string path = "Assets/Star/";
foreach(string file in images)
{
string thepath = Path.Combine(path,file);
await Task.Delay(46);
BitmapImage Image = new BitmapImage();
Image.UriSource = new Uri(this.BaseUri, thepath);
StarImage.Source = Image;
}
}
Now everytime the new image is loaded in to the StarImage, it flickers, as far as I know their is no way to stop this because it is the effect of loading a new image in the image box, however does anyone know any alternatives to stop this and give the effect of an animation?
I think some sort of buffering technique may reduce or eliminate the flickering problem you have.
I've never done this in c#, but essentially you draw to an image which is not yet visible referred to as the buffer, and then make it visible when the image is completely drawn.
This may help.
try this:
private async void Button7_Click(object sender, RoutedEventArgs e)
{
string[] images = new string[] { "Star_00001.png", "Star_00002.png", "Star_00003.png", "Star_00004.png", "Star_00005.png", "Star_00006.png", "Star_00007.png", "Star_00008.png" };
string path = "Assets/Star/";
foreach (string file in images)
{
string thepath = Path.Combine(path, file);
await Task.Delay(46);
BitmapImage Image = new BitmapImage();
Image.BeginInit();
Image.UriSource = new Uri(this.BaseUri, thepath);
Image.CacheOption = BitmapCacheOption.OnLoad;
Image.EndInit();
StarImage.Source = Image;
}
}
I've been racking my brains for months trying to solve this, and then I found this post. It helped me solve this! I can't understand for the life of me why Microsoft keeps changing the syntax to do things in windows.
How to set Background of a Button without flicker?
I have an issue that I think has not been covered in the multitude of other WPF image loading issues. I am scanning in several images and passing them to a "Preview Page". The preview page takes the image thumbnails and displays what a printout would look like via a generated bitmap.
The weird thing to me is, it will work fine if I run the program the first time. Upon reaching the end of the process and hitting "start over", the preview will return blank. I am creating the BitmapImage in a method that saves the bitmap as a random file name so I do not believe theres a lock on the file the second time around. Also, if I go to look at the temporary file created through explorer, it is drawn correctly so I know the appropriate data is getting to it.
Finally, when I navigate away from this page, I am clearing necessary data. I'm really perplexed and any help would be appreciated.
//Constructor
public Receipt_Form() {
InitializeComponent();
printData = new List<Object>();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e) {
// populates global variable fileName
var task = System.Threading.Tasks.Task.Factory.StartNew(() => outputToBitmap()); task.ContinueWith(t => setImage(fileName),
System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());
// I started the image creation in a separate thread because I
// thought it may be blocking the UI thread, but it didn't matter
}
private void setImage(string imageURI) {
BitmapImage image;
using (FileStream stream = File.OpenRead(imageURI)) {
image = new BitmapImage();
image.BeginInit();
image.StreamSource = stream;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit();
}
receiptPreview.Source = image;
//this works the first iteration but not the second, though the temp file is created successfully
}
Found the issue - the Modern UI container was getting cleared when transitioning off the page.
I am working on a C# project, and I am having a strange problem. I have an Image control and I am trying to display an image within it. There is no error or exception thrown, but the image doesn't display.
Below is the code I am using:
BitmapImage image = new BitmapImage();
image.UriSource = new Uri("images\\low_battery.png", UriKind.Relative);
imageIcon.Source = image;
imageIcon.Visibility = System.Windows.Visibility.Visible;
I have the directory image and the image file low_battery.png running in the same directory as to where the executable is running from.
Thanks for any help you can provide.
A few suggestions:
1) You can get the exception from WPF if you subscribe to the ImageFailed even on imageIcon and the and DownloadFailed event on BitmapImage. Then put breakpoints in those methods and see what it says.
2) Before setting UriSource, call image.BeginInit(). After setting UriSource, call image.EndInit(). To help debug the problem, you can subscribe to the ImageFailed event on imageIcon and DownloadFailed on BitmapImage. So the final code looks like this:
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri("/images/low_battery.png", UriKind.Relative);
image.DownloadFailed += image_DownloadFailed;
image.EndInit();
imageIcon.ImageFailed += imageIcon_ImageFailed;
imageIcon.Source = image;
imageIcon.Visibility = System.Windows.Visibility.Visible;
and further down:
void imageIcon_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
// Breakpoint here
}
void image_DownloadFailed(object sender, ExceptionEventArgs e)
{
// Breakpoint here
}
3) Another way to do this is to embed images directly into your project. Do that by adding an images folder into your project, then adding the image, and setting the type to "Resource"
Either call image.BeginInit() before setting image.UriSource and image.EndInit() afterwards, or simply use the BitmapImage constructor that takes an Uri as argument:
var uri = new Uri("images\\low_battery.png", UriKind.Relative);
imageIcon.Source = new BitmapImage(uri);
I am trying to change the code http://sites.google.com/site/webcamlibrarydotnet/winfrom-and-csharp-sample-code-and-download from picture box to image or bitmap as I dont want to display any image or plan to display, all I want is that it will output the image to file.
I have tried changing the webcam.cs from PictureBox _FrameImage to Bitmap _FrameImage and PictureBox ImageControl to Bitmap ImageControl and casting (Bitmap) at e.WebCamImage
As well as changing it on the main form:
private void bWebcam_Click(object sender, EventArgs e)
{
WebCam webcam = new WebCam();
Bitmap image = null;
webcam.InitializeWebCam(ref image);
webcam.Start();
webcam.Stop();
FileStream fstream = new FileStream("testWebcam.jpg", FileMode.Create);
image.Save(fstream, System.Drawing.Imaging.ImageFormat.Jpeg);
fstream.Close();
}
Unhappyly it doesnt seem to work so
how could I change it from picture
box to Bitmap or Image or similar
storage before saving it to a file or
save it to file directly ?
The source code I am using is:
http://sites.google.com/site/webcamlibrarydotnet/winfrom-and-csharp-sample-code-and-download
Instead of using the WebCam class, why not just use the WebCamCapture class directly (since you are not displaying this in a form) and handle the ImageCapture event directly. The event argument for the event contains the Image. You could, in the event handler save the image to disk. Alternately, if you want to use the sample and the WebCam class, and you have a form. Use a PictureBox but leave it hidden (set Visible to false) and then just copy the image from there and save to disk when you need to.
Here is some sample code of using the WebCamCapture class instead of the WebCam class. It should be noted that this code is based on the sample code from the link provided in the question. I have kept the style of the sample so that code lines up.
Edit: Adding example of using WebCamCapture instead of WebCam class. This code should be used to modify Form1.cs in the sample code.
// Instead of having WebCam as member variable, have WemCamCapture
WebCamCapture webCam;
// Change the mainWinForm_Load function
private void mainWinForm_Load(object sender, EventArgs e)
{
webCam = new WebCamCapture();
webCam.FrameNumber = ((ulong)(0ul));
webCam.TimeToCapture_milliseconds = 30;
webCam.ImageCaptured += webcam_ImageCaptured;
}
// Add the webcam Image Captured handler to the main form
private void webcam_ImageCaptured(object source, WebcamEventArgs e)
{
Image imageCaptured = e.WebCamImage;
// You can now stop the camera if you only want 1 image
// webCam.Stop();
// Add code here to save image to disk
}
// Adjust the code in bntStart_Click
// (yes I know there is a type there, but to make code lineup I am not fixing it)
private void bntStart_Click(object sender, Event Args e)
{
webCam.Start(0);
}
Using reflector you can see that internally the WebCam class uses a timer to simulate a framerate. Therefore calling start and stop right after each other will never generate an image since the application doesnt handle application events (and therefore the timer tick event) in between starting and stopping. You should register on the ImageChanged event and call stop in there.
Good luck
** Edit: the start logic **
public void Start(ulong FrameNum)
{
try
{
this.Stop();
this.mCapHwnd = capCreateCaptureWindowA("WebCap", 0, 0, 0, this.m_Width, this.m_Height, base.Handle.ToInt32(), 0);
Application.DoEvents();
SendMessage(this.mCapHwnd, 0x40a, 0, 0);
SendMessage(this.mCapHwnd, 0x432, 0, 0);
this.m_FrameNumber = FrameNum;
this.timer1.Interval = this.m_TimeToCapture_milliseconds;
this.bStopped = false;
this.timer1.Start();
}
catch (Exception exception)
{
MessageBox.Show("An error ocurred while starting the video capture. Check that your webcamera is connected properly and turned on.\r\n\n" + exception.Message);
this.Stop();
}
}
In WebCam.cs you have:
public void InitializeWebCam(ref System.Windows.Forms.PictureBox ImageControl)
{
webcam = new WebCamCapture();
webcam.FrameNumber = ((ulong)(0ul));
webcam.TimeToCapture_milliseconds = FrameNumber;
webcam.ImageCaptured += new WebCamCapture.WebCamEventHandler(webcam_ImageCaptured);
_FrameImage = ImageControl;
}
void webcam_ImageCaptured(object source, WebcamEventArgs e)
{
_FrameImage.Image = e.WebCamImage;
}
If you modify the ImageCaptured code you can do what you want: e.WebCamImage is an Image.
for example you could change/add constructor to accept a file name and, in the ImageCaptured event, you could save image to file.
If I've got a Silverlight Image control that downloads from a full URL, how can I get the size (in bytes) of the downloaded image without making another web call?
I can't find anything on the Image or the BitmapImage source behind it that would tell me. And even the DownloadProgress event on the BitmapImage only gives a percentage.
I never noticed it before, but that is kind of a strange gap in the framework...
You'll probably have to download the image by itself using a WebClient object. That'll give you a stream of bytes. You can check the length of the stream, and then create a bitmap from the stream.
Code to set up the web client and begin the download (note, it's an async call, so we assign an event handler to fire when it completes the download.)
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
Uri someImageUri = new Uri("http://www.somesite.com/someimage.jpg");
wc.OpenReadAsync(someImageUri);
Here's an example of what the event handler method might look like:
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
System.IO.Stream imageStream = e.Result;
long imageSize = imageStream.Length;
BitmapImage bi = new BitmapImage();
bi.SetSource(imageStream);
Image image = new Image();
image.Source = bi;
}
Obviously, if you already have an image control on your form, you wouldn't need to create a new one, or if you did want to create it, you'll have to add it to a parent panel of some kind...
~Chris