C# 如何使用Silverlight 2计算加载图像的大小?
我正在将一个图像加载到背景中,我希望包含所有图像的silverlight画布能够调整到图像大小(或我确定的最大或最小值),无论图像大小如何。因此,我做了以下工作: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));
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