C# 如何使用Silverlight 2计算加载图像的大小?

C# 如何使用Silverlight 2计算加载图像的大小?,c#,silverlight,C#,Silverlight,我正在将一个图像加载到背景中,我希望包含所有图像的silverlight画布能够调整到图像大小(或我确定的最大或最小值),无论图像大小如何。因此,我做了以下工作: private int ImageMargin = 4; public Page() { InitializeComponent(); BitmapImage bi = new BitmapImage(new Uri("1.jpg", UriKind.Relative));

我正在将一个图像加载到背景中,我希望包含所有图像的silverlight画布能够调整到图像大小(或我确定的最大或最小值),无论图像大小如何。因此,我做了以下工作:

private int ImageMargin = 4;

    public Page()
    {
        InitializeComponent();

        BitmapImage bi = new BitmapImage(new Uri("1.jpg", UriKind.Relative));
        backgroundImage.Source = bi;
        bi.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(bi_DownloadProgress);

        backgroundImage.SizeChanged += new SizeChangedEventHandler(backgroundImage_SizeChanged);

    }

    void bi_DownloadProgress(object sender, DownloadProgressEventArgs e)
    {
        if (e.Progress == 100)
        {
          LayoutRoot.Height = backgroundImage.Height + ImageMargin * 2;
          LayoutRoot.Width = backgroundImage.Width + ImageMargin * 2;
        }
    }
private int-ImageMargin=4;
公共网页()
{
初始化组件();
BitmapImage bi=新的BitmapImage(新Uri(“1.jpg”,UriKind.Relative));
backgroundImage.Source=bi;
bi.DownloadProgress+=新事件处理程序(bi_DownloadProgress);
backgroundImage.SizeChanged+=新的SizeChangedEventHandler(backgroundImage\u SizeChanged);
}
void bi_DownloadProgress(对象发送方,DownloadProgressEventArgs e)
{
如果(如进度==100)
{
LayoutRoot.Height=背景图像.Height+图像边距*2;
LayoutRoot.Width=背景图像.Width+图像边距*2;
}
}
图像加载正确,但无论我将backgroundImage.Height/Width(off.Loaded事件、.SizeChanged事件[1],使用边框[2]等)放在何处,它总是返回0.0或NaN。我做错了什么

[1]
[2]

您可能需要等待一个UI循环周期,以确保Silverlight有机会更新布局。此外,您还必须确保图像实际上是可见的。我实际上写了一个小程序,从图像二进制文件中获取图像大小。缺点是您必须通过WebClient显式下载图像,但好处是您可以在不实际显示任何内容的情况下了解尺寸:

namespace StatMap.Silverlight.Services.UIHelpers
{
    public static class ImageSizeExtractor
    {
        public static bool TryGetImageSize(byte[] buf, out int width, out int height)
        {
            return TryGetPngSize(buf, out width, out height) || TryGetJpegSize(buf, out width, out height);
        }

        private static bool IsPng(byte[] buf)
        {
            return (buf.Length > 8)&&(buf[0] == 137) && (buf[1] == 80) && (buf[2] == 78) && (buf[3] == 71)
                   && (buf[4]==13)&&(buf[5]== 10)&&(buf[6]== 26)&&(buf[7]== 10);
        }

        private static bool TryGetPngSize(byte[] buf, out int width, out int height)
        {
            width = 0;
            height = 0;
            if (IsPng(buf))
            {
                int index = -1;
                for (int i = 8; i < buf.Length - 12;i++)
                {
                    if ((buf[i]==0x49)&&(buf[i+1]==0x48)&&(buf[i+2]==0x44)&&(buf[i+3]==0x52))
                    {
                        index = i + 4;
                        break;
                    }
                }

                if (index<0)
                {
                    return false;
                }
                width = buf[index + 3] + buf[index + 2]*256;
                height = buf[index + 7] + buf[index + 6]*256;
                return true;
            }
            return false;
        }

        private static bool TryGetJpegSize(byte[] buf, out int width, out int height)
        {
            //static char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height) {
            //Check for valid JPEG image
            int i = 0; // Keeps track of the position within the file
            width = 0;
            height = 0;
            if (buf[i] == 0xFF && buf[i + 1] == 0xD8 && buf[i + 2] == 0xFF && buf[i + 3] == 0xE0)
            {
                i += 4;
                // Check for valid JPEG header (null terminated JFIF)
                if (buf[i + 2] == 'J' && buf[i + 3] == 'F' && buf[i + 4] == 'I' && buf[i + 5] == 'F' &&
                    buf[i + 6] == 0x00)
                {
                    //Retrieve the block length of the first block since the first block will not contain the size of file
                    int blockLength = buf[i]*256 + buf[i + 1];
                    while (i < buf.Length)
                    {
                        i += blockLength; //Increase the file index to get to the next block
                        if (i >= buf.Length) return false; //Check to protect against segmentation faults
                        if (buf[i] != 0xFF) return false; //Check that we are truly at the start of another block
                        if (buf[i + 1] == 0xC0)
                        {
                            //0xFFC0 is the "Start of frame" marker which contains the file size
                            //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
                            width = buf[i + 5]*256 + buf[i + 6];
                            height = buf[i + 7]*256 + buf[i + 8];
                            return true;
                        }
                        i += 2; //Skip the block marker
                        blockLength = buf[i]*256 + buf[i + 1]; //Go to the next block
                    }
                    return false; //If this point is reached then no size was found
                }
                return false;
            }
            return false;
        }
    }
}
namespace StatMap.Silverlight.Services.UIHelpers
{
公共静态类ImageSizeExtractor
{
公共静态bool TryGetImageSize(字节[]buf,out int width,out int height)
{
返回TryGetPngSize(buf,输出宽度,输出高度)| | TryGetPngSize(buf,输出宽度,输出高度);
}
专用静态bool IsPng(字节[]buf)
{
返回值(buf.Length>8)&&(buf[0]==137)&&(buf[1]==80)&(buf[2]==78)&(buf[3]==71)
&&(buf[4]==13)&(buf[5]==10)&(buf[6]==26)&(buf[7]==10);
}
专用静态bool TryGetPngSize(字节[]buf,out int width,out int height)
{
宽度=0;
高度=0;
如果(IsPng(buf))
{
int指数=-1;
对于(int i=8;i

希望这有帮助。

您可能需要等待一个UI循环周期,以确保Silverlight有机会更新布局。此外,您还必须确保图像实际上是可见的。我实际上写了一个小程序,从图像二进制文件中获取图像大小。缺点是您必须通过WebClient显式下载图像,但好处是您可以在不实际显示任何内容的情况下了解尺寸:

namespace StatMap.Silverlight.Services.UIHelpers
{
    public static class ImageSizeExtractor
    {
        public static bool TryGetImageSize(byte[] buf, out int width, out int height)
        {
            return TryGetPngSize(buf, out width, out height) || TryGetJpegSize(buf, out width, out height);
        }

        private static bool IsPng(byte[] buf)
        {
            return (buf.Length > 8)&&(buf[0] == 137) && (buf[1] == 80) && (buf[2] == 78) && (buf[3] == 71)
                   && (buf[4]==13)&&(buf[5]== 10)&&(buf[6]== 26)&&(buf[7]== 10);
        }

        private static bool TryGetPngSize(byte[] buf, out int width, out int height)
        {
            width = 0;
            height = 0;
            if (IsPng(buf))
            {
                int index = -1;
                for (int i = 8; i < buf.Length - 12;i++)
                {
                    if ((buf[i]==0x49)&&(buf[i+1]==0x48)&&(buf[i+2]==0x44)&&(buf[i+3]==0x52))
                    {
                        index = i + 4;
                        break;
                    }
                }

                if (index<0)
                {
                    return false;
                }
                width = buf[index + 3] + buf[index + 2]*256;
                height = buf[index + 7] + buf[index + 6]*256;
                return true;
            }
            return false;
        }

        private static bool TryGetJpegSize(byte[] buf, out int width, out int height)
        {
            //static char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height) {
            //Check for valid JPEG image
            int i = 0; // Keeps track of the position within the file
            width = 0;
            height = 0;
            if (buf[i] == 0xFF && buf[i + 1] == 0xD8 && buf[i + 2] == 0xFF && buf[i + 3] == 0xE0)
            {
                i += 4;
                // Check for valid JPEG header (null terminated JFIF)
                if (buf[i + 2] == 'J' && buf[i + 3] == 'F' && buf[i + 4] == 'I' && buf[i + 5] == 'F' &&
                    buf[i + 6] == 0x00)
                {
                    //Retrieve the block length of the first block since the first block will not contain the size of file
                    int blockLength = buf[i]*256 + buf[i + 1];
                    while (i < buf.Length)
                    {
                        i += blockLength; //Increase the file index to get to the next block
                        if (i >= buf.Length) return false; //Check to protect against segmentation faults
                        if (buf[i] != 0xFF) return false; //Check that we are truly at the start of another block
                        if (buf[i + 1] == 0xC0)
                        {
                            //0xFFC0 is the "Start of frame" marker which contains the file size
                            //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
                            width = buf[i + 5]*256 + buf[i + 6];
                            height = buf[i + 7]*256 + buf[i + 8];
                            return true;
                        }
                        i += 2; //Skip the block marker
                        blockLength = buf[i]*256 + buf[i + 1]; //Go to the next block
                    }
                    return false; //If this point is reached then no size was found
                }
                return false;
            }
            return false;
        }
    }
}
namespace StatMap.Silverlight.Services.UIHelpers
{
公共静态类ImageSizeExtractor
{
公共静态bool TryGetImageSize(字节[]buf,out int width,out int height)
{
返回TryGetPngSize(buf,输出宽度,输出高度)| | TryGetPngSize(buf,输出宽度,输出高度);
}
专用静态bool IsPng(字节[]buf)
{
返回值(buf.Length>8)&&(buf[0]==137)&&(buf[1]==80)&(buf[2]==78)&(buf[3]==71)
&&(buf[4]==13)&(buf[5]==10)&(buf[6]==26)&(buf[7]==10);
}
专用静态bool TryGetPngSize(字节[]buf,out int width,out int height)
{
宽度=0;
高度=0;
如果(IsPng(buf))
{
int指数=-1;
对于(int i=8;i