How do I load a BitmapImage for processing in Silverlight? - silverlight

The following code will only show a size for my bitmap (needed for processing) if I uncomment the commented lines. This doesn't seem the right to go about things but it's all I've come up with so far that works. I don't want to display my bitmap as an image in a UI element, I just want to process it.
BitmapImage bmpi;
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
bmpi = new BitmapImage(new Uri("multicolor.png", UriKind.Relative));
//Image img = new Image();
//img.Source = bmpi;
//LayoutRoot.Children.Add(img);
//LayoutRoot.Children.Clear();
MessageBox.Show(bmpi.PixelWidth.ToString());
}

To load the image upfront, you need to set CreateOptions to None from its default value, DelayCreation.
Then you can get the width in the ImageOpened event.
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
bmpi = new BitmapImage();
bmpi.CreateOptions = BitmapCreateOptions.None;
bmpi.ImageOpened += new EventHandler<RoutedEventArgs>(bmpi_ImageOpened);
bmpi.UriSource = new Uri("multicolor.png", UriKind.RelativeOrAbsolute);
}
void bmpi_ImageOpened(object sender, RoutedEventArgs e)
{
MessageBox.Show(bmpi.PixelWidth.ToString());
}

Related

WPF Richtextbox Write to .txt file

string okunanmetin;
string Progfilepath;
private void btnSelect_Click(object sender, RoutedEventArgs e)
{
richtextboxEdit.Document.Blocks.Remove(richtextboxEdit.Document.Blocks.ElementAt(0));
Progfilepath = "C:/Users/SC/Desktop/test.txt";
okunanmetin = File.ReadAllText(Progfilepath);
richtextboxEdit.Document.Blocks.Add(new Paragraph(new Run(okunanmetin)));
}
As you can see, I can insert a .txt file into the richtextbox. I am making changes in this text that I added. After this change I want to save to the same file.
I tried to do as seen below.
private void btnSave_Click(object sender, RoutedEventArgs e)
{
LoadXamlPackage( "C:/Users/SC/Desktop/test.txt");
}
void LoadXamlPackage(string _fileName)
{
TextRange range;
FileStream fStream;
if (File.Exists(_fileName))
{
range = new TextRange(richtextboxEdit.Document.ContentStart, richtextboxEdit.Document.ContentEnd);
fStream = new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
range.Save(fStream, DataFormats.Text);
fStream.Close();
}
}
It didn't work the way I wanted.
When I click the save button, it saves the changes but not everything.
Thanks for Support
Hello Guys I solved the problems like the below.
private void btnSave_Click(object sender, RoutedEventArgs e)
{
if (File.Exists(Progfilepath))
{
TextRange textRange = new TextRange(richtextboxEdit.Document.ContentStart, richtextboxEdit.Document.ContentEnd);
File.WriteAllText(Progfilepath, textRange.Text);
}
}

WPF - Why would Loading image from relative path during runtime fail *unless* I examine the object in debugger?

Made a new test project just for this, with a button and an image. MyImage.png is placed in the project's debug working directory, and NOT included in the project.
This works fine, with an absolute path specified:
private void BtnLoadFromFile_Click(object sender, RoutedEventArgs e)
{
Uri fileUri = new Uri("C:/blah/blah/blah/MyImage.png");
BitmapImage myimage = new BitmapImage(fileUri);
Imagebox.Source = myimage;
}
This does NOT show any image, with a relative path:
private void BtnLoadFromFile_Click(object sender, RoutedEventArgs e)
{
Uri fileUri = new Uri("MyImage.png", UriKind.Relative);
BitmapImage myimage = new BitmapImage(fileUri);
Imagebox.Source = myimage;
}
However, I noticed that the relative path DOES work if I set a breakpoint at the last line, examine myimage's properties (it holds data indicating MyImage.png was successfully found), then continue execution. At which point the image shows up. I'm using Visual Studio 2019 Community.
I'm very confused why this is happening.
That looks like a bug. A workaround would be to set BitmapCacheOption.OnLoad:
private void BtnLoadFromFile_Click(object sender, RoutedEventArgs e)
{
var fileUri = new Uri("MyImage.png", UriKind.Relative);
var myImage = new BitmapImage();
myImage.BeginInit();
myImage.UriSource = fileUri;
myImage.CacheOption = BitmapCacheOption.OnLoad;
myImage.EndInit();
Imagebox.Source = myImage;
}
Or always use an absolute URI:
private void BtnLoadFromFile_Click(object sender, RoutedEventArgs e)
{
var fileUri = new Uri(Path.Combine(Environment.CurrentDirectory, "MyImage.jpg"));
var myImage = new BitmapImage(fileUri);
Imagebox.Source = myImage;
}

mjpeg streaming in wpf not working

I develop a WPF app for mjpg streaming. I include the code here
public partial class MainWindow : Window
{
MjpegDecoder _mjpeg;
public MainWindow()
{
InitializeComponent();
_mjpeg = new MjpegDecoder();
_mjpeg.FrameReady += _mjpeg_FrameReady;
}
void _mjpeg_FrameReady(object sender, FrameReadyEventArgs e)
{
// What to write to get BitmapImage
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
_mjpeg.ParseStream(new Uri("http://155.41.145.37/mjpg/video.mjpg"));
}
}
What I need to write to get the bitmap from the frameReadyEventArgs and how to assign that bitmap to a WPF Image control
I've never used MJPEG Decoder library but if you go to their WPF example you'll find this:
private void mjpeg_FrameReady(object sender, FrameReadyEventArgs e)
{
image.Source = e.BitmapImage;
}
FrameReadyEventArgs should already have BitmapImage
public class FrameReadyEventArgs : EventArgs
{
...
public BitmapImage BitmapImage;
}

Get target control from DoubleAnimation Completed event in WPF?

I'm hoping someone can help me with what I thought would be a relatively straight forward problem.
I am setting a fadeout animation in code using a DoubleAnimation object. It fades out an image, and then fires off the Completed event when it's done.
I would like to get the name of the control that the fadeout animation was applied to from within the event handler, but I can't find a way.
Any help appreciated. Thanks.
DispatcherTimer timer = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
image1.Visibility = System.Windows.Visibility.Visible;
image2.Visibility = System.Windows.Visibility.Collapsed;
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void FadeOut(UIElement element)
{
DoubleAnimation FadeOut = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(0.5)));
FadeOut.Completed += new EventHandler(FadeOut_Completed);
element.BeginAnimation(OpacityProperty, FadeOut);
}
void FadeOut_Completed(object sender, EventArgs e)
{
// How to find out which control was targeted?
}
void timer_Tick(object sender, EventArgs e)
{
if (image1.Visibility == System.Windows.Visibility.Visible)
{
FadeOut(image1);
//image1.Visibility = System.Windows.Visibility.Collapsed;
//image2.Visibility = System.Windows.Visibility.Visible;
}
}
The following code gives you the target of completed animation. Place it in FadeOut_Completed() handler:
DependencyObject target = Storyboard.GetTarget(((sender as AnimationClock).Timeline as AnimationTimeline))
However this will only work if animation target object is specified. To do it add the following to FadeOut() method:
Storyboard.SetTarget(FadeOut, element);

Silverlight : BitmapImage to WriteableBitmap

I can successfully load the following Bitmap like this and display it within an Image control on the view.
var bitmapImage = new BitmapImage
{
UriSource =
new Uri("../Images/Test.JPG", UriKind.Relative)
};
However as soon as I add this line to create a WriteableBitmap out of the bitmap,
var w = new WriteableBitmap(bitmapImage);
I get a Runtime error at the line above: "Object reference not set to an instance of an object."
It seems the BitmapImage creation is delayed, could that be? How should I fix this?
Update:
I am now trying this but the openImage seems never to be hit. (even without trying to make it synchronous, it still fails) What is wrong here?
var image = new BitmapImage();
image.ImageOpened += (sender, args) => resetEventBitmap.Set();
image.ImageFailed += (o, eventArgs) =>
{
resetEventBitmap.Set();
throw eventArgs.ErrorException;
};
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.UriSource = uri;
resetEventBitmap.WaitOne();
Thanks,
Reference:
http://www.blog.ingenuitynow.net/Silverlight+Creating+A+WriteableBitmap+From+A+Uri+Source.aspx
Basically, bitmap image has a dependency property "CreateOptions" which, by default, is set to "DelayCreation". This causes the bitmap to be delayed for rendering until after it's needed. Hence, this causes our "object reference not set to an instance of an object" error. To fix this, we have to break the bitmap creation out of the writeablebitmap constructor, change this option, and then put it back in. In vb.net this looks like:
Dim tmpUri As New Uri(yourpath.ToString)
Dim bmp As New BitmapImage
bmp.CreateOptions = BitmapCreateOptions.None
bmp.UriSource = tmpUri
Dim wb As New WriteableBitmap(bmp)
BitmapImage _classField;
void LoadImageFunction()
{
_classField = new BitmapImage();
_classField.ImageOpened += new EventHandler<RoutedEventArgs>(bi_ImageOpened);
_classField.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(bi_ImageFailed);
//sorry.. totally forgot about order :)
_classField.UriSource = new Uri("../some/uri", UriKind.Relative);
}
void bi_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
//something has happend
throw e.ErrorException;
}
void bi_ImageOpened(object sender, RoutedEventArgs e)
{
//image is loaded.. now we can work with it..
var w = new WriteableBitmap(_classField);
}
img1 = new BitmapImage(new Uri("/PrjName;component/Images/image01.jpg", UriKind.RelativeOrAbsolute));
img2 = new BitmapImage(new Uri("/PrjName;component/Images/image02.jpg", UriKind.RelativeOrAbsolute));
img1.CreateOptions = BitmapCreateOptions.None;
img2.CreateOptions = BitmapCreateOptions.None;
img1.ImageOpened += new EventHandler<RoutedEventArgs>(img1_ImageOpened);
img2.ImageOpened += new EventHandler<RoutedEventArgs>(img2_ImageOpened);
void img2_ImageOpened(object sender, RoutedEventArgs e)
{
load2 = true;
}
void img1_ImageOpened(object sender, RoutedEventArgs e)
{
load1 = true;
}
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
while (!load1 && !load2)
{ }
WriteableBitmap x = new WriteableBitmap(img1);
WriteableBitmap y = new WriteableBitmap(img2);
}
This should work. it did for me..! It makes it a lil' complicated, but that's how it works!

Resources