no set picture in control.image with uri - wpf

My Solution Explorer image :
My code in PopupWinHelper :
var img = new Image
{
BitmapEffect = new DropShadowBitmapEffect(),
Stretch = Stretch.Fill,
Source = new BitmapImage(new Uri("/WpfApplication1;component/images/PopupImage.png"))
};
My code in Mainwindow :
private void button1_Click(object sender, RoutedEventArgs e)
{
cuswin.PopupWinHelper.ShowPopUp(150,300,"asdad", new Thickness(20));
}
Why does this error occur?
Then I'm use :
var img = new Image
{
BitmapEffect = new DropShadowBitmapEffect(),
Stretch = Stretch.Fill,
Source = new BitmapImage(new Uri("/images/PopupImage.png", UriKind.Relative))
};
No error. But the picture is not shown in image.

Source = new BitmapImage(new Uri("/WpfApplication1;component/images/PopupImage.png", UriKind.Relative))
should work, assumed PopupImage.png is a Resource.
Regards

Related

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;
}

Displaying an Image from a DB in an Image Control

I've saved an image in my DataBase in a parameter type image and I've done this with:
private void btnAceptar_Click(object sender, RoutedEventArgs e)
{
UsuariosBLL bll = new UsuariosBLL();
UsuariosBO user = new UsuariosBO();
PerfilBO perfil = cmbperf.SelectedItem as PerfilBO;
//........
user.Imagen = ConvertImageToByteArray(ruta);
bll.InsertarFilaUsuarios(user);
MessageBox.Show("Se insertó");
//.......
}
where the method ConvertToByteArray convert the image selected in a Byte Array
public byte[] ConvertImageToByteArray(string path)
{
byte[] ImageByte=null;
try
{
FileStream fs = new FileStream(path,FileMode.Open,FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
ImageByte = br.ReadBytes((int)fs.Length);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return ImageByte;
}
and now I just wanna retrieve the image selecting a different user in my combobox.
I've tried like this:
private void cmbUsuarios_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
UsuariosBO user = e.AddedItems[0] as UsuariosBO;
//.....
MemoryStream ms = new MemoryStream(user.Imagen);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
imgFoto = img;
usuario = user;
}
But a error born:
Can not implicitly convert type 'System.Drawing.Image' to 'System.Windows.Controls.Image'
I understand what it means but I don't know how to fix it...
thanks !!
Instead of creating a System.Drawing.Image from the byte stream, you should create a WPF ImageSource and assign that to the Source property of your ImageControl.
One way to do this is by creating a BitmapImage:
using (var ms = new MemoryStream(user.Imagen))
{
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.StreamSource = ms;
img.EndInit();
imgFoto.Source = img;
}
Or alternatively a BitmapFrame:
using (var ms = new MemoryStream(user.Imagen))
{
imgFoto.Source = BitmapFrame.Create(ms,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}

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!

WPF: Get specify image from touch

I was added picture as a children to layer called "canvas". By the following code:
if (addChild)
{
Image i = new Image();
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(path, UriKind.Absolute);
src.EndInit();
i.Source = src;
i.Width = 200;
i.IsManipulationEnabled = true;
double rotAngle = Rand.GetRandomDouble(-3.14/4, 3.14/4);
i.RenderTransform = new MatrixTransform(Math.Cos(rotAngle), -Math.Sin(rotAngle),
Math.Sin(rotAngle), Math.Cos(rotAngle), Rand.GetRandomDouble(0, this.Width - i.Width), Rand.GetRandomDouble(0, this.Height - i.Width));
canvasImages.Add(i);
canvas.Children.Add(i);
Canvas.SetZIndex(i, canvas.Children.Count-1);
addedFiles.Add(path);
maxZ++;
}
Here is the problem. I'm trying to make an event called "canvas_TouchDown" which can detect the specify picture when I touched it so that it will get the center of that image object.
List<Image> canvasImages = new List<Image>();
private void canvas_TouchDown(object sender, TouchEventArgs e)
{
foreach (Image canvasImage in canvasImages)
{
if (canvasImage.AreAnyTouchesCaptured == true)
{
System.Diagnostics.Debug.WriteLine("I found image that you touch");
}
}
}
However, there is nothing happened. I also try to use PersistId property but it doesn't work. Have any suggestion?
Regard,
C.Porawat
If you are adding the image to the canvas, touching it and expecting the canvas to receive the touch you will be disappointed. You should either listen to "touch down" on the image or "preview touch down" on the canvas.

WPF, Image MouseDown Event

I have an control with a mouse down event where Id like to chnage the Image when the image is clicked. But I cant seem to alter ANY of the images properties in the event.
Event
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
BitmapImage bitImg = new BitmapImage();
bitImg.BeginInit();
bitImg.UriSource = new Uri("./Resource/Images/Bar1.png", UriKind.Relative);
bitImg.EndInit();
((Image)sender).Source = null;
((Image)sender).Width = 100;
((Image)sender).Visibility = Visibility.Hidden;
}
The event does fire, and even the .Visibility property does not alter the image and make it hidden.
What am I doing wrong?
Assuming the file is in your application, you need to use the Pack URI scheme:
var img = sender as Image;
BitmapImage bmp = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/Bar1.png"));
img.Source = bmp;
In the above example, this would indicate a subfolder in your project of Resources/Images.

Resources