Image loading from localhost is not working on silverlight - silverlight

I making simple silverlight application.
I need to access and use an image from localhost,
I write down my code like this
Book4.Source = new BitmapImage(new Uri("http://localhost/test/book2.png", UriKind.Absolute));
It doesn't make any errors, but It can't load any image.
//P.S. I didn't use asp. It is OOB app.
* EDITED: To include additional content for the question.
public void changeValue_book()
{
if (empty_book[3] == true && book_index == 3)
{
empty_book[3] = false;
Book4.Visibility = Visibility.Visible;
Book3.Visibility = Visibility.Visible;
Book3.Source = null;
Book3.Source = new BitmapImage(new Uri("http://localhost/test/book1.png", UriKind.Absolute));
//Book3.Source = new BitmapImage(new Uri("Resource/책1.png", UriKind.Relative));
}
else if (empty_book[4] == true && book_index == 4)
{
empty_book[4] = false;
Book5.Visibility = Visibility.Visible;
Book4.Visibility = Visibility.Visible;
Book4.Source = new BitmapImage(new Uri("http://localhost/test/book2.png", UriKind.Absolute));
}
else if (empty_book[5] == true && book_index == 5)
{
}
}

If you're able to access the expected image from your web browser when you navigate to http://localhost/test/book2.png then try the following:
Uri uri = new Uri("http://localhost/test/book2.png", UriKind.Absolute);
ImageSource imageSource = new BitmapImage(uri);
Book4.Source = imageSource;
EDITED
If you're images reside on http://localhost/test/yourimagename.png, but your Silverlight application is hosted within an https:// or from the Filesystem you will not be able to load the images at all. The Silverlight Image class and MediaElement class for progressive downloads (media, images, ASX, etc.) are not allowed Cross-scheme access.
Please see this link for more details:
http://msdn.microsoft.com/en-us/library/cc189008(v=vs.95).aspx

Maybe it is clientaccesspolicy.xml problem. When the address of the site where SL is loaded is different from address where you want download data from, than it can be blocked. That clientaccesspolicy.xml file also must specify that SL can go deeper into subdirs. (here is some example).
Now I realize, that this problem would throw some cross domain policy error...
Either way, check that too, just to be sure.

Related

Listbox default image

In an windows phone 7 application I'm populating one listbox with remote images .. since the images are not downloaded instantly I want to load a default image until the remote image are ready. What is the best way to do this?
Until now, I have the following code skelton:
public partial class RemoteImage : PhoneApplicationPage
{
ObservableCollection<Image> images = new ObservableCollection<Image> { };
public RemoteImage()
{
InitializeComponent();
listImage.ItemsSource = GetAllImages();
}
private ImageSource GetImageSource(string fileName)
{
return new BitmapImage(new Uri(fileName, UriKind.Absolute));
}
private ObservableCollection<Image> GetAllImages()
{
WebClient restClient = new WebClient();
restClient.OpenReadAsync(new Uri(#"http://www.my-api.com"));
restClient.OpenReadCompleted += new OpenReadCompletedEventHandler(onReadComplete);
return images;
}
private void onReadComplete(object sender, OpenReadCompletedEventArgs args)
{
Stream stm = args.Result;
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
RootObject ro = (RootObject)ser.ReadObject(stm);
foreach (var item in ro.items)
{
images.Add(new Image{ PhotoSource = GetImageSource(item.image.link) });
}
}
}
If you know, how many images you would need, you should create first the number of default images. Load some image file directly at your project and use it as imageSource for default images. Then, when you'll finish downloading remote images, you should set the new image source for each.
When I got the similar issue, I had some problems with defining which exactly downloaded image refers to which object on page. (As you remember the WebClient objects work asynchronously, so if you have 10 images on page and download 10 remote images at once you can't say that the first downloaded image is the first on page) To solve this you could create more complicated download method (I used a delegate to transfer the id/name of image) or use recursion (Start download method for first image, download it, set source for one on page, download next one...).

passing values between silverlight applications

I have created a Silverlight Business Application which runs as my main silverlight page. For each hyperlink button on my "menu" I launch another Silverlight Application which is created as a different project in Visual Studio. These are non-Business Applications.
Everything is working well. However I'm trying to pass a value from my main SL application to the SL application inside.
I have been googling a lot and cannot find an answer.
As I understand the InitParam is used between ASP and SL, and not between SL apps.
Since the App config is launched for the first SL app and the app config for the second application in never lauched, I'm not able to use that (thats at least my understanding)
The value I want to pass is the login name and role, which is possible to get from webcontext in the Silverlight Business application, but I'm unable to get webcontext in the non-Business application which run inside.
This is how I launch my SL app inside the main SL app:
public Customers()
{
InitializeComponent();
this.Title = ApplicationStrings.CustomersPageTitle;
if (WebContext.Current.User.IsInRole("Users") || WebContext.Current.User.IsInRole("Administrators"))
{
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri("customers.xap", UriKind.Relative));
}
}
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
string appManifest = new StreamReader(Application.GetResourceStream(new StreamResourceInfo(e.Result, null),
new Uri("AppManifest.xaml", UriKind.Relative)).Stream).ReadToEnd();
XElement deploymentRoot = XDocument.Parse(appManifest).Root;
List<XElement> deploymentParts =
(from assemblyParts in deploymentRoot.Elements().Elements() select assemblyParts).ToList();
Assembly asm = null;
AssemblyPart asmPart = new AssemblyPart();
foreach (XElement xElement in deploymentParts)
{
string source = xElement.Attribute("Source").Value;
StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(e.Result, "application/binary"), new Uri(source, UriKind.Relative));
if (source == "customers.dll")
{
asm = asmPart.Load(streamInfo.Stream);
}
else
{
asmPart.Load(streamInfo.Stream);
}
}
UIElement myData = asm.CreateInstance("customers.MainPage") as UIElement;
stackCustomers.Children.Add(myData);
stackCustomers.UpdateLayout();
}
Anyone?
i agree with ChrisF ,I think that Prism or MEF can resolve you problem.
any way,do some search on the web and look for these two classes:
**
LocalMessageSender
LocalMessageReceiver
**
good luck

Save Silverlight webcam image (ImageSource) to Server

This is as far as I've gotten. What code would I write to save a captured image to the server? Without any dialog prompting for a save location. Similar to the way Facebook does it. (I've been unable to find examples online)
void CaptureSource_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
{
capturedImage.ImageSource = e.Result;
stopCapture(); // turns off webcam
}
It is not that simple.
Create a WCF service on the server.
Consume it on the silverlight client.
Call service method to send an image to the server.
Save it on the server with custom logic.
Or, if this is too complicated - follow this tutorial. It is rather compact RESTful approach demo.
I did i before,
Firstly
ImageTools is good library not must but a good library, you may use.
Beside this you shoul check for permission for camera access. Then here is the code,
Hope helps,
/Capture image part/
_captureSource.CaptureImageCompleted += ((s, args) =>
{
//some other stuffs
domainServiceObject.PR_PATIENTPHOTOs.Clear();
photo = new PR_PATIENTPHOTO();
ImageTools.ExtendedImage eimg=args.Result.ToImage();
var encoder=new ImageTools.IO.Png.PngEncoder();
Stream stream= eimg.ToStreamByExtension("png");
if (stream.Length > 512000)
{
eimg= ExtendedImage.Resize(eimg, 240, new NearestNeighborResizer());
stream = eimg.ToStreamByExtension("png");
}
/Reload Image Part/
//note photo.photo is byte[]
photo = domainServerObject.PR_PATIENTPHOTOs.FirstOrDefault();
if (photo != null)
{
using (MemoryStream ms = new MemoryStream(photo.PHOTO, 0, photo.PHOTO.Length))
{
ms.Write(photo.PHOTO, 0, photo.PHOTO.Length);
BitmapImage img = new BitmapImage();
img.SetSource(ms);
imagePatientPhoto.Source = img;
}
}

Properly cancel an image download in Silverlight

I have a set of Image elements that I use to download pictures. All the pictures have to be downloaded, but I wish to download the picture the user is looking at in the first place. If the user changes the viewed picture, I wish to cancel the downloads in progress to get the viewed picture as fast as possible.
To start a download I write: myImage.Source = new BitmapImage(theUri);.
How should I cancel it?
myImage.Source = null; ?
act on the BitmapImage ?
a better solution ?
I don't wish to download the picture by code to keep the benefit of the browser cache.
This is definitely doable -- I just tested it to make sure. Here is a quick class you can try:
public partial class Page : UserControl
{
private WebClient m_oWC;
public Page()
{
InitializeComponent();
m_oWC = new WebClient();
m_oWC.OpenReadCompleted += new OpenReadCompletedEventHandler(m_oWC_OpenReadCompleted);
}
void StartDownload(string sImageURL)
{
if (m_oWC.IsBusy)
{
m_oWC.CancelAsync();
}
m_oWC.OpenReadAsync(new Uri(sImageURL));
}
void m_oWC_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
BitmapImage oBMI = new BitmapImage();
oBMI.SetSource(e.Result);
imgMain.Source = oBMI;
}
}
This works just like you wanted (I tested it). Everytime you call StartDownload with the URL of an image (presumably whenever a user clicks to the next image) if there is a current download in progress it is canceled. The broswer cache is also definitely being used (I verified with fiddler), so cached images are loaded ~ instantly.

How to render an <image> in a background WPF process?

I'm taking Silverlight XAML and sending it to a web service that renders the XAML in a STA thread and generates a PNG image. All the XAML renders correctly except the <image> entries which 'appear' to load correctly when their Source property is set in WPF but the PNG does not show the referenced image - what am I doing wrong ?
The core of the code that I am using is as below. The value object is a DTO from Silverlight that contains the XAML in the string that ends up as the sXAML local property and the Image URI is in the value.ImageURL property.
var canvas = (FrameworkElement)XamlReader.Load(new XmlTextReader(new StringReader(sXAML)));
var obj = canvas.FindName("BGImage");
Image img = null;
if (obj != null)
{
img = obj as Image;
img.ImageFailed += img_ImageFailed;
img.Source = new BitmapImage(new Uri(value.ImageURL, UriKind.Absolute));
}
canvas.Arrange(new Rect(new Size(463d, 381d)));
canvas.UpdateLayout();
var mem = new MemoryStream();
var bmp = new RenderTargetBitmap(463, 381, 96d, 96d, PixelFormats.Pbgra32);
bmp.Render(canvas);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
encoder.Save(mem);
FileStream fs = new FileStream("D:\\out.png", FileMode.Create);
mem.WriteTo(fs);
fs.Close();
NB: The img_ImageFailed event handler is never invoked indicating that the img Source assignment was successful in some way.
Things I would try:
1) In your WPF app, if you 'render' your dynamically loaded Canvas to display in a Window, does it all work (images included)?
2) Have you tried attaching a Loaded handler to the img object to see when the image is actually loaded?
3) Assuming #1 works - where are the images located (are they on the internet/local web server)? If you put a breakpoint in the code on
bmp.Render(canvas);
and wait a while before stepping on - does the image then appear in the rendered output?
I suspect the image is being 'downloaded' asynchronously and you are rendering the Canvas too early, before the Image object has resolved its source.
[UPDATE 29-Jan-09]
possible solution
I copied you code down exactly and gave it a try. When I used a 'local' image location (eg. "c:\images\splash.jpg") the image was rendered fine in the output jpeg. When I used a URL (eg. "http://localhost/images/splash.jpg") it did NOT appear (as you describe).
So I modified your code as follows (to try and FORCE the image to be downloaded - will only work for http: image references) --
if (obj != null)
{
img = obj as Image;
// new stuff
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = getCachedURLStream(new Uri(ImageURL));
bi.EndInit();
img.BeginInit();
img.Source = bi;
img.EndInit();
//img.ImageFailed += img_ImageFailed;
//img.Loaded += new RoutedEventHandler(img_Loaded);
//img.Source = new BitmapImage(new Uri(ImageURL, UriKind.Absolute));
}
public static Stream getCachedURLStream(Uri url)
{
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
WebResponse response;
webrequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
response = webrequest.GetResponse();
Stream s = response.GetResponseStream();
BufferedStream bs = new BufferedStream(s, 8192);
return bs;
}
(the getCachedURLStream method is from synchronous image loading - it's kinda extraneous but I just wanted a quick chunk of code to test) and it seemed to then work (image visible in JPEG). Maybe that will work in your scenario?

Resources