Answered by:
Creating a Thumbnail in Silverlight

Question
-
I want to let the user select an image using the OpenFileDialog, create a thumbnail, and show the thumbnail in an image control, but nothing is showing using my code.
private void btnUploadAsIs_Click(object sender, RoutedEventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = false; bool? result = ofd.ShowDialog(); if (!result.HasValue || result.Value == false) return; BitmapImage imageSource = new BitmapImage(); try { imageSource.SetSource(ofd.File.OpenRead()); WriteableBitmap img; ImageHelper imgHelper = new ImageHelper(); // Call the method that creates the thumbnail img = imgHelper.CreateThumbnailImage(imageSource, 100); imgAsIs.Source = img; } catch (Exception) { } }
and here's the method that creates the thumbnail:
public WriteableBitmap CreateThumbnailImage(BitmapImage bi, int maxWidth) { double reduceBy; double originalWidth; double originalHeight; Image image = new Image(); image.Source = bi; originalWidth = bi.PixelWidth; originalHeight = bi.PixelHeight; if (originalWidth > originalHeight) { reduceBy = originalWidth / maxWidth; } else { reduceBy = originalHeight / maxWidth; } double cx = originalWidth / reduceBy; double cy = originalWidth / reduceBy; WriteableBitmap wb1 = new WriteableBitmap((int)cx, (int)cy); ScaleTransform transform = new ScaleTransform(); transform.ScaleX = cx; transform.ScaleY = cy; wb1.Render(image, transform); wb1.Invalidate(); WriteableBitmap wb2 = new WriteableBitmap((int)cx, (int)cy); for (int i = 0; i < wb2.Pixels.Length; i++) { wb2.Pixels[i] = wb1.Pixels[i]; } wb2.Invalidate(); return wb2; }
As I step through the code all seems to be in good shape and hte WritebleBitmap has 10,000 pixels in it, so I would expect to see it.
"imgAsIs" is an image control in a Silverlight user control.
If I use the BitmapImage imageSourse to set the image source, I can see the image in the image control, but when I use the CreateThumbnailImage method, it doesn't work.
I appreciate any help you can offer. Thank you.
- Moved by Franklin ChenMicrosoft employee Thursday, June 5, 2014 7:01 AM SL
Thursday, June 5, 2014 4:44 AM
Answers
-
There is nothing obviously wrong with the code you posted, but there's not enough to debug ourselves.
A problem you will find is almost anyone who does any serious xaml development will use MVVM. So personally I have little experience of directly setting properties like that. That code would be called from a viewmodel which set a bound property in anything I wrote. There'd be no click event involved.
I suggest you take that code makes the thumbnail and put it into a new window with an image control. If the image appears then you know your problem lies elsewhere.
It might be a thread thing and the UI is effectively locked whilst you're in the button click event.
To work round that I would probably begininvoke off another thread.
Here's a rather over engineered piece of code will call a method from a different thread and delay it until after your click event ( and any locking of anything ) is completed.
I suppose you could just nail this on right now and give it a twirl.
Storyboard sb = new Storyboard(); sb.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300)); sb.Completed += new EventHandler(delegate(object s, EventArgs a) { Dispatcher.BeginInvoke(() => { // Call your method }); }); sb.Begin();
I would refactor this stuff into a method of some sort
BitmapImage imageSource = new BitmapImage(); try { imageSource.SetSource(ofd.File.OpenRead()); WriteableBitmap img; ImageHelper imgHelper = new ImageHelper(); // Call the method that creates the thumbnail img = imgHelper.CreateThumbnailImage(imageSource, 100); imgAsIs.Source = img; } catch (Exception) { }
Friday, June 6, 2014 10:53 AM
All replies
-
Hi,
I'm afraid that it is not the correct forum about this issue, since this forum is to discuss WPF.
So I have moved this thread to Silverlight forum for better response.
Thanks for your understanding.
Best regards,
FranklinWe are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.Thursday, June 5, 2014 7:03 AM -
I think this should be in a Silverlight forum rather than WPF.
When you say "it doesn't work".
I would advise you to elaborate.
If you step into the method you see wb2 created OK?
I would guess you do as that code looks to be cut and pasted out this article:
That means you can read the file and the code makes the thumbnail works if that checks out.
I would think that means your problem probably lies in this piece of code
imgAsIs.Source = img;
And that's not doing what you hope it will.
OR
Some code comes along later and changes that source
OR
The thumbnail created is somehow incompatible with imgAsIs - which is kind of the first issue.
Thursday, June 5, 2014 7:10 AM -
Franklin,
I made the post here because there are no msdn supported forums for Silverlight. Im not sure that was helpful.
Thursday, June 5, 2014 2:58 PM -
Thanks, but this doesn't really answer my question. Yes, my code did come from Jeff's sample above so I would expect it to work.
Still hoping I'll get some help on this even though this post was removed from an msdn supported forum.
Thanks.
Thursday, June 5, 2014 4:06 PM -
There is nothing obviously wrong with the code you posted, but there's not enough to debug ourselves.
A problem you will find is almost anyone who does any serious xaml development will use MVVM. So personally I have little experience of directly setting properties like that. That code would be called from a viewmodel which set a bound property in anything I wrote. There'd be no click event involved.
I suggest you take that code makes the thumbnail and put it into a new window with an image control. If the image appears then you know your problem lies elsewhere.
It might be a thread thing and the UI is effectively locked whilst you're in the button click event.
To work round that I would probably begininvoke off another thread.
Here's a rather over engineered piece of code will call a method from a different thread and delay it until after your click event ( and any locking of anything ) is completed.
I suppose you could just nail this on right now and give it a twirl.
Storyboard sb = new Storyboard(); sb.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300)); sb.Completed += new EventHandler(delegate(object s, EventArgs a) { Dispatcher.BeginInvoke(() => { // Call your method }); }); sb.Begin();
I would refactor this stuff into a method of some sort
BitmapImage imageSource = new BitmapImage(); try { imageSource.SetSource(ofd.File.OpenRead()); WriteableBitmap img; ImageHelper imgHelper = new ImageHelper(); // Call the method that creates the thumbnail img = imgHelper.CreateThumbnailImage(imageSource, 100); imgAsIs.Source = img; } catch (Exception) { }
Friday, June 6, 2014 10:53 AM -
OK Thanks, I'll give it a shot.Friday, June 6, 2014 3:14 PM
-
I suppose you could just nail this on right now and give it a twirl.
Storyboard sb = new Storyboard(); sb.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300)); sb.Completed += new EventHandler(delegate(object s, EventArgs a) { Dispatcher.BeginInvoke(() => { // Call your method }); }); sb.Begin();
I would refactor this stuff into a method of some sort
BitmapImage imageSource = new BitmapImage(); try { imageSource.SetSource(ofd.File.OpenRead()); WriteableBitmap img; ImageHelper imgHelper = new ImageHelper(); // Call the method that creates the thumbnail img = imgHelper.CreateThumbnailImage(imageSource, 100); imgAsIs.Source = img; } catch (Exception) { }
Sunday, June 8, 2014 11:29 AM