none
如何预先知道图片的大小 (Image加载前) ? RRS feed

  • 问题

  •  

    现在用一个 Silverlight 需加加载用户的图片,图片从用户本地电脑打开或者从网络的 url  上加载。

     

    问题在于,图片需要 1:1 显示,不能缩小。但 Silverlight 的大小却是固定的,我现在需要实现,如果图片过大,就自动增大 Silverlight 的高和宽。

     

    如果在加载前知道图片的大小,这当然好办,但如何在加载图片前得到图片的大小呢?

    2008年12月6日 4:12

答案

  • http://silverlight.net/blogs/msnow/default.aspx

     

     

    Silverlight Tip of the Day #13 - How to Get an Images Dimensions in Silverlight.

     

    Since Silverlight is based upon an asynchronized model, getting an image width and height immediately after loading it is not possible. However, you can monitor its download progress and obtain the image dimensions once the progress has reached 100%.

    Below is a sample that demonstrates how to do this. Few important notes:

    • BitmapImage requires the namespace System.Windows.Media.Imaging;
    • ActualWidth and ActualHeight are calculated values. The calculation happens after a layout pass. Therefore, the image must be in the tree in order for hits size to be accounted for. Thus my call to GameCanvas.Children.Add(grass);
    • The image you are adding to your canvas must be first added to your Silverlight application project in Visual Studio. Make certain your path to this image is correct.
    • The call to Dispatcher.BeginInvoke(delegate() { … } ); is required before you obtain the Width/Height or they might be intermittently zero.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Media.Imaging;
     
    namespace SilverlightApplication12
    {
        
        public partial class Page : UserControl
        {
            private Image grass;
     
            public Page()
            {
                InitializeComponent();
                LoadImage("grass.png");
            }
     
            private void LoadImage(string path)
            {
                Uri uri = new Uri(path, UriKind.Relative);
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.UriSource = uri;
                bitmapImage.DownloadProgress += 
                    new EventHandler<DownloadProgressEventArgs>(bitmapImage_DownloadProgress);
                
                grass = new Image();
                grass.Source = bitmapImage;
                GameCanvas.Children.Add(grass);
            }
     
            void bitmapImage_DownloadProgress(object sender, DownloadProgressEventArgs e)
            {
                if (e.Progress == 100)
                {
                    Dispatcher.BeginInvoke(delegate()
                    {
                       double height = grass.ActualHeight;
                       double width = grass.ActualWidth;
                    });
                }
            }
        }
    }

    Page.xaml:

    <UserControl x:Class="SilverlightApplication12.Page"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width="400" Height="300">
        <Grid x:Name="LayoutRoot" Background="White">
            <ContentControl x:Name="MyContent">
                <Canvas x:Name="GameCanvas" ></Canvas>
            </ContentControl>                              
        </Grid>
    </UserControl>
    2008年12月9日 13:23
  • 读取本地图片的方法

    Code Snippet

       

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
    OpenFileDialog openFileDialog1 = new OpenFileDialog();
    if ((bool)openFileDialog1.ShowDialog())
    {
    System.IO.Stream stream = openFileDialog1.File.OpenRead();
    System.Windows.Media.Imaging.BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage();
    bi.SetSource(stream);
    img.Source = bi;
    stream.Close();
    }

    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    msg.Text = img.ActualWidth.ToString();
    }



     
    2008年12月10日 1:04
    版主

全部回复

  •  <img  id="img2"   src=""   style="visibility:hidden;position:absolute;top=-10000"/>   
     <script   language="javascript">  
      function  GetWidth()  
      {   
         return img2.width;  
      }

      function  GetHeight()  
      {   
         return img2.height;  
      }   
      </script> 

     

    页面添加js,然后sl把图片路径传给页面js后,sl调用js的获取图片的宽高就可以了

     

    2008年12月6日 6:20
    版主
  • http://silverlight.net/blogs/msnow/default.aspx

     

     

    Silverlight Tip of the Day #13 - How to Get an Images Dimensions in Silverlight.

     

    Since Silverlight is based upon an asynchronized model, getting an image width and height immediately after loading it is not possible. However, you can monitor its download progress and obtain the image dimensions once the progress has reached 100%.

    Below is a sample that demonstrates how to do this. Few important notes:

    • BitmapImage requires the namespace System.Windows.Media.Imaging;
    • ActualWidth and ActualHeight are calculated values. The calculation happens after a layout pass. Therefore, the image must be in the tree in order for hits size to be accounted for. Thus my call to GameCanvas.Children.Add(grass);
    • The image you are adding to your canvas must be first added to your Silverlight application project in Visual Studio. Make certain your path to this image is correct.
    • The call to Dispatcher.BeginInvoke(delegate() { … } ); is required before you obtain the Width/Height or they might be intermittently zero.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Media.Imaging;
     
    namespace SilverlightApplication12
    {
        
        public partial class Page : UserControl
        {
            private Image grass;
     
            public Page()
            {
                InitializeComponent();
                LoadImage("grass.png");
            }
     
            private void LoadImage(string path)
            {
                Uri uri = new Uri(path, UriKind.Relative);
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.UriSource = uri;
                bitmapImage.DownloadProgress += 
                    new EventHandler<DownloadProgressEventArgs>(bitmapImage_DownloadProgress);
                
                grass = new Image();
                grass.Source = bitmapImage;
                GameCanvas.Children.Add(grass);
            }
     
            void bitmapImage_DownloadProgress(object sender, DownloadProgressEventArgs e)
            {
                if (e.Progress == 100)
                {
                    Dispatcher.BeginInvoke(delegate()
                    {
                       double height = grass.ActualHeight;
                       double width = grass.ActualWidth;
                    });
                }
            }
        }
    }

    Page.xaml:

    <UserControl x:Class="SilverlightApplication12.Page"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width="400" Height="300">
        <Grid x:Name="LayoutRoot" Background="White">
            <ContentControl x:Name="MyContent">
                <Canvas x:Name="GameCanvas" ></Canvas>
            </ContentControl>                              
        </Grid>
    </UserControl>
    2008年12月9日 13:23
  • HiYouAll 的方法已经派上用场。

    不过,这只能解决从 url 加载图片时的大小,还是无法解决从本地电脑打开图片时的大小。
    2008年12月9日 16:14
  • 上面的方法也是先加载啊,加载前是无法得到大小的
    2008年12月10日 0:41
    版主
  • 读取本地图片的方法

    Code Snippet

       

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
    OpenFileDialog openFileDialog1 = new OpenFileDialog();
    if ((bool)openFileDialog1.ShowDialog())
    {
    System.IO.Stream stream = openFileDialog1.File.OpenRead();
    System.Windows.Media.Imaging.BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage();
    bi.SetSource(stream);
    img.Source = bi;
    stream.Close();
    }

    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    msg.Text = img.ActualWidth.ToString();
    }



     
    2008年12月10日 1:04
    版主