How to Set the Source Property for a WPF Image?
- Dick Bowman
- Posts: 235
- Joined: Thu Jun 18, 2009 4:55 pm
- Contact:
How to Set the Source Property for a WPF Image?
My explorations of WPF/XAML continue - here's the latest obstacle I've met.
I have a Window which contains an Image, here's the XAML defining the Image...
<Image Height="356" HorizontalAlignment="Left" Margin="0,59,0,0" Stretch="Fill"
VerticalAlignment="Top" Width="394" Name="imgArticle"
Source="d:\dick\temp\saucy.jpg" />
The Window displays the Image correctly.
But I want to change the Source within my APL code, and all I get is DOMAIN ERROR...
Exploration shows me...
]displayr {(⎕DR ⍵)(⍴⍴⍵)(⍴⍵)⍵}frmAcquire.imgArticle.Source
┌4─────────────────────────────────────────────┐
│ ┌1─┐ ┌0─┐ │
│ 326 │ 0│ │ 0│ file:///d:/dick/temp/saucy.jpg │
│ └~─┘ └~─┘ │
└¯2────────────────────────────────────────────┘
So I know that Source is a Pointer (some sort of dog?), and just assigning a character vector won't cut any mustard (tried it, got a DOMAIN ERROR). Read the DotNet Interface Guide, and found out about ByRef, so...
p←⎕new ByRef (⊂'file:///d:/dick/temp/saucy.jpg')
]displayr {(⎕DR ⍵)(⍴⍴⍵)(⍴⍵)⍵ ⍵.Value}p
┌5────────────────────────────────────────────────────────────┐
│ ┌1─┐ ┌0─┐ ┌30────────────────────────────┐ │
│ 326 │ 0│ │ 0│ Dyalog.ByRef │file:///d:/dick/temp/saucy.jpg│ │
│ └~─┘ └~─┘ └──────────────────────────────┘ │
└¯2───────────────────────────────────────────────────────────┘
But...
frmAcquire.imgArticle.Source←p
DOMAIN ERROR
frmAcquire.imgArticle.Source←p
∧
frmAcquire.imgArticle.Source←⊂p
DOMAIN ERROR
frmAcquire.imgArticle.Source←⊂p
∧
I'm sure I'm missing something glaringly obvious - anyone care to enlighten me? I've looked at the Microsoft site and see similar questions asked, but the answers seem to go into a maze of data bindings and so forth - not only incomprehensible to a dumb APLer, but seeming to avoid my wildly rash concept that "the image should come from whatever file the user decides they want to look at".
I have a Window which contains an Image, here's the XAML defining the Image...
<Image Height="356" HorizontalAlignment="Left" Margin="0,59,0,0" Stretch="Fill"
VerticalAlignment="Top" Width="394" Name="imgArticle"
Source="d:\dick\temp\saucy.jpg" />
The Window displays the Image correctly.
But I want to change the Source within my APL code, and all I get is DOMAIN ERROR...
Exploration shows me...
]displayr {(⎕DR ⍵)(⍴⍴⍵)(⍴⍵)⍵}frmAcquire.imgArticle.Source
┌4─────────────────────────────────────────────┐
│ ┌1─┐ ┌0─┐ │
│ 326 │ 0│ │ 0│ file:///d:/dick/temp/saucy.jpg │
│ └~─┘ └~─┘ │
└¯2────────────────────────────────────────────┘
So I know that Source is a Pointer (some sort of dog?), and just assigning a character vector won't cut any mustard (tried it, got a DOMAIN ERROR). Read the DotNet Interface Guide, and found out about ByRef, so...
p←⎕new ByRef (⊂'file:///d:/dick/temp/saucy.jpg')
]displayr {(⎕DR ⍵)(⍴⍴⍵)(⍴⍵)⍵ ⍵.Value}p
┌5────────────────────────────────────────────────────────────┐
│ ┌1─┐ ┌0─┐ ┌30────────────────────────────┐ │
│ 326 │ 0│ │ 0│ Dyalog.ByRef │file:///d:/dick/temp/saucy.jpg│ │
│ └~─┘ └~─┘ └──────────────────────────────┘ │
└¯2───────────────────────────────────────────────────────────┘
But...
frmAcquire.imgArticle.Source←p
DOMAIN ERROR
frmAcquire.imgArticle.Source←p
∧
frmAcquire.imgArticle.Source←⊂p
DOMAIN ERROR
frmAcquire.imgArticle.Source←⊂p
∧
I'm sure I'm missing something glaringly obvious - anyone care to enlighten me? I've looked at the Microsoft site and see similar questions asked, but the answers seem to go into a maze of data bindings and so forth - not only incomprehensible to a dumb APLer, but seeming to avoid my wildly rash concept that "the image should come from whatever file the user decides they want to look at".
Visit http://apl.dickbowman.com to read more from Dick Bowman
- MikeHughes
- Posts: 86
- Joined: Thu Nov 26, 2009 9:03 am
- Location: Market Harborough, Leicestershire, UK
Re: How to Set the Source Property for a WPF Image?
Hi Dick,
I am sure there is a better way but I found this the best way so far. I agree not obvious :-)
I have tested it with png files which I usually use - not with jpg - I am hoping it will work with those too.
image.source←GetImageSource 'd:\dick\temp\saucy.jpg'
∇r←GetImageSource file
r←'ImageSource' GetResource file
∇
r←type GetResource ra;txt
txt←'<ResourceDictionary '
txt,←'xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" '
txt,←'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" '
txt,←' >'
txt,←'<',type,' x:Key="item">',ra,'</',type,'>'
txt,←'</ResourceDictionary>'
r←#.WPF.LoadXaml txt
r←r[⊂'item']
∇
I am sure there is a better way but I found this the best way so far. I agree not obvious :-)
I have tested it with png files which I usually use - not with jpg - I am hoping it will work with those too.
image.source←GetImageSource 'd:\dick\temp\saucy.jpg'
∇r←GetImageSource file
r←'ImageSource' GetResource file
∇
r←type GetResource ra;txt
txt←'<ResourceDictionary '
txt,←'xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" '
txt,←'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" '
txt,←' >'
txt,←'<',type,' x:Key="item">',ra,'</',type,'>'
txt,←'</ResourceDictionary>'
r←#.WPF.LoadXaml txt
r←r[⊂'item']
∇
- MikeHughes
- Posts: 86
- Joined: Thu Nov 26, 2009 9:03 am
- Location: Market Harborough, Leicestershire, UK
Re: How to Set the Source Property for a WPF Image?
Sorry first line was supposed to be
frmAcquire.imgArticle.Source←GetImageSource 'd:\dick\temp\saucy.jpg'
frmAcquire.imgArticle.Source←GetImageSource 'd:\dick\temp\saucy.jpg'
- StefanoLanzavecchia
- Posts: 113
- Joined: Fri Oct 03, 2008 9:37 am
- MikeHughes
- Posts: 86
- Joined: Thu Nov 26, 2009 9:03 am
- Location: Market Harborough, Leicestershire, UK
Re: How to Set the Source Property for a WPF Image?
I like that - worked a treat :-)
- Dick Bowman
- Posts: 235
- Joined: Thu Jun 18, 2009 4:55 pm
- Contact:
Re: How to Set the Source Property for a WPF Image?
Thank you both for your responses (apologies for my tardiness - I spent yesterday battling with the fraudsters and incompetents "running" my local trains).
For the benefit of anyone else who reacts the same way to seeing the sort of code littering MSDN I've made a little function...
z←ImageSource w;⎕USING;ic
⍝ Set Image Source (from MSDN via Stefano Lanzavecchia)
⎕USING←#.WPF.Using
ic←⎕NEW ImageSourceConverter''
z←ic.ConvertFrom⊂w
To my eyes the APL transliteration looks a lot neater than the original whatever-it-was; but I'm a bit uneasy about pulling in that umbrella setting for ⎕USING.
If the better-informed can bear with me a little longer - are there any well-known pros and cons of the two solutions, banging together a bit of XAML versus figuring out what's in .NET and how to use it?
For the benefit of anyone else who reacts the same way to seeing the sort of code littering MSDN I've made a little function...
z←ImageSource w;⎕USING;ic
⍝ Set Image Source (from MSDN via Stefano Lanzavecchia)
⎕USING←#.WPF.Using
ic←⎕NEW ImageSourceConverter''
z←ic.ConvertFrom⊂w
To my eyes the APL transliteration looks a lot neater than the original whatever-it-was; but I'm a bit uneasy about pulling in that umbrella setting for ⎕USING.
If the better-informed can bear with me a little longer - are there any well-known pros and cons of the two solutions, banging together a bit of XAML versus figuring out what's in .NET and how to use it?
Visit http://apl.dickbowman.com to read more from Dick Bowman
Re: How to Set the Source Property for a WPF Image?
Here is another way of doing it taken from here:
or alternatively, using a constructor of BitmapImage:
Pierre Gilbert
Code: Select all
img ← ⎕new Image
bi ← ⎕new BitmapImage
bi.BeginInit
bi.UriSource ← ⎕new Uri (⊂'d:/dick/temp/saucy.jpg')
bi.EndInit
img.Source ← bi
or alternatively, using a constructor of BitmapImage:
Code: Select all
bi ← ⎕new BitmapImage (⎕new Uri (⊂'d:/dick/temp/saucy.jpg'))
img.Source ← bi
Pierre Gilbert
Re: How to Set the Source Property for a WPF Image?
Hello Dick, in case you are like me and want to keep your important bitmaps (like the company logo) and icons in the WS so the users don't mess with them, here is the code that works for me in Unicode Dyalog and using WPF:
⍝ Read the file and and Assign it to a Variable at Development Time
MyPicture_jpg ← ⎕UCS System.IO.File.ReadAllBytes (⊂'C:\MyPicture.jpg')
⍝ Render the File as a Bitmap Object at Runtime
MS ← ⎕NEW MemoryStream (⍴MyPicture_jpg)
MS.WriteByte¨ Convert.ToByte¨ MyPicture_jpg
bi ← ⎕NEW System.Windows.Media.Imaging.BitmapImage
bi.BeginInit
bi.StreamSource ← MS
bi.EndInit
img ← ⎕NEW System.Windows.Controls.Image
img.Source ← bi
img.Stretch ← img.Stretch.Uniform
⍝ AND FOR AN ICON:
⍝ Read the file and Assign it to a Variable at Development Time
MyIcon_ico ← ⎕UCS System.IO.File.ReadAllBytes (⊂'C:\MyIcon.ico')
⍝ Render the File as an Icon at Runtime
MS ← ⎕NEW MemoryStream (⍴MyIcon_ico)
MS.WriteByte¨ Convert.ToByte¨ MyIcon_ico
bf ← System.Windows.Media.Imaging.BitmapFrame.Create MS
win ← ⎕NEW Window
win.Icon ← bf
⍝ Read the file and and Assign it to a Variable at Development Time
MyPicture_jpg ← ⎕UCS System.IO.File.ReadAllBytes (⊂'C:\MyPicture.jpg')
⍝ Render the File as a Bitmap Object at Runtime
MS ← ⎕NEW MemoryStream (⍴MyPicture_jpg)
MS.WriteByte¨ Convert.ToByte¨ MyPicture_jpg
bi ← ⎕NEW System.Windows.Media.Imaging.BitmapImage
bi.BeginInit
bi.StreamSource ← MS
bi.EndInit
img ← ⎕NEW System.Windows.Controls.Image
img.Source ← bi
img.Stretch ← img.Stretch.Uniform
⍝ AND FOR AN ICON:
⍝ Read the file and Assign it to a Variable at Development Time
MyIcon_ico ← ⎕UCS System.IO.File.ReadAllBytes (⊂'C:\MyIcon.ico')
⍝ Render the File as an Icon at Runtime
MS ← ⎕NEW MemoryStream (⍴MyIcon_ico)
MS.WriteByte¨ Convert.ToByte¨ MyIcon_ico
bf ← System.Windows.Media.Imaging.BitmapFrame.Create MS
win ← ⎕NEW Window
win.Icon ← bf
- Dick Bowman
- Posts: 235
- Joined: Thu Jun 18, 2009 4:55 pm
- Contact:
Re: How to Set the Source Property for a WPF Image?
Discovered another little WPF oddity related to the above...
My application wants to let the user view the image and then - at their discretion - delete the file.
But instead the status window says (among other things)...
"The process cannot access the file 'd:\dick\temp\image.jpg' because it is being used by another process."
Which the rational APLer might feel is a little weird (at my kindest here) because there's only me using the file and the only application I have running is the one that just used the file and wants to delete it.
Solution - obviously - is to modify Pierre's function to include BitmapCacheOption.OnLoad, thusly...
bitmap←ImageSource w;⎕USING
⍝ Get Image Source (closing file after use)
⎕USING←#.UTIL.WPF.Using
bitmap←⎕NEW BitmapImage
bitmap.BeginInit
bitmap.UriSource←⎕NEW Uri(⊂w)
bitmap.CacheOption←BitmapCacheOption.OnLoad
bitmap.EndInit
Did Microsoft design this stuff? Or did it just grow at random?
My application wants to let the user view the image and then - at their discretion - delete the file.
But instead the status window says (among other things)...
"The process cannot access the file 'd:\dick\temp\image.jpg' because it is being used by another process."
Which the rational APLer might feel is a little weird (at my kindest here) because there's only me using the file and the only application I have running is the one that just used the file and wants to delete it.
Solution - obviously - is to modify Pierre's function to include BitmapCacheOption.OnLoad, thusly...
bitmap←ImageSource w;⎕USING
⍝ Get Image Source (closing file after use)
⎕USING←#.UTIL.WPF.Using
bitmap←⎕NEW BitmapImage
bitmap.BeginInit
bitmap.UriSource←⎕NEW Uri(⊂w)
bitmap.CacheOption←BitmapCacheOption.OnLoad
bitmap.EndInit
Did Microsoft design this stuff? Or did it just grow at random?
Visit http://apl.dickbowman.com to read more from Dick Bowman
- StefanoLanzavecchia
- Posts: 113
- Joined: Fri Oct 03, 2008 9:37 am
Re: How to Set the Source Property for a WPF Image?
Something similar (only the error message would be much less explicative) if you did (assuming you have a folder called "c:\trash\"):
Code: Select all
:Trap 0
⎕FUNTIE'c:\trash\bla.dcf'⎕FCREATE 0
:EndTrap
t←'c:\trash\bla.dcf'⎕FTIE 0
tn←'c:\trash\bla.dcf'⎕NTIE 0
'c:\trash\bla.dcf'⎕NERASE tn