Determine PixelWidth and PixelHeight for JPEG image in Silverlight 2B1
I'm new in Silverlight, but I'm very new in .NET and C# too, because I'm a java developer. But I have a project where I need to use something cool. This cool is Silverlight.
In my project I have thousands of jpeg images, but I need to know what is that images exact dimension.
In WPF it's very easy, using BitmapImage.PixelWidth and PixelHeight. But in Silverlight 2B1 these properties are not present.
I found a solution in java language. I "translated" to Silverlight and C#, and it's works!
The core function (updated 27/04/2008):
|
using System.IO;
using System.Windows;
namespace JpegPixelDimensionTest
{
public class JPEGUtil
{
/// <summary>
/// Based: http://forum.java.sun.com/thread.jspa?threadID=554733&messageID=2717319 and http://www.obrador.com/essentialjpeg/headerinfo.htm
/// </summary>
/// <param name="fis"></param>
/// <returns></returns>
public static Size getJPEGDimension(Stream fis)
{
byte[] buf = new byte[64 * 1024];
// check for SOI marker
if (0xFF != fis.ReadByte() || 0xD8 != fis.ReadByte())
{
return new Size(0, 0);
}
while (0xFF == fis.ReadByte())
{
int marker = fis.ReadByte();
int len = (fis.ReadByte() << 8 | fis.ReadByte()) - 2;
fis.Read(buf, 0, len);
// Start of frame marker (FFC0)
if ( /* baseline */0xC0 == marker
|| /* non-baseline*/ 0xC1 == marker
|| /* progressive Huffman */ 0xC2 == marker
|| /* arithmetic coding */ 0xC9 == marker)
{
int height = buf[1] << 8 | buf[2];
int width = buf[3] << 8 | buf[4];
return new Size(width, height);
}
// JFIF marker (FFE0)
else if (0xE0 == marker)
{
if (/* Units in pixel */ 0 == buf[7])
{
int width = buf[8] << 8 | buf[9];
int height = buf[10] << 8 | buf[11];
return new Size(width, height);
}
}
}
return new Size(0, 0);
}
}
}
|
Simple test sample. After starting this example, you need to write an url from your domain.
|
using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace JpegPixelDimensionTest
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(inputURL.Text, UriKind.Absolute));
request.BeginGetResponse(new AsyncCallback(ReadCallback), request);
}
catch (Exception exc)
{
result.Text = exc.Message;
}
}
private void ReadCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
// Read the whole image into a MemoryStream
MemoryStream ms = new MemoryStream();
Stream sourceStream = response.GetResponseStream();
int bufSize = 64 * 1024;
byte[] buf = new byte[bufSize];
int readed;
while ((readed = sourceStream.Read(buf, 0, bufSize)) > 0)
{
ms.Write(buf, 0, readed);
}
// Read jpeg dimension
ms.Seek(0, SeekOrigin.Begin);
Size jpegSize = JPEGUtil.getJPEGDimension(ms);
result.Text = "Width = " + jpegSize.Width.ToString() + " Height = " + jpegSize.Height.ToString();
ms.Seek(0, SeekOrigin.Begin);
// Show image
BitmapImage mainImage = new BitmapImage();
mainImage.SetSource(ms);
image.Source = mainImage;
}
catch (Exception exc)
{
result.Text = exc.Message;
}
}
}
}
|
XAML source
|
<UserControl x:Class="JpegPixelDimensionTest.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="URL: " />
<TextBox x:Name="inputURL" Width="400"/>
<Button Content="Load jpeg image!"
Click="Button_Click"/>
</StackPanel>
<TextBox x:Name="result"
IsReadOnly="True"
/>
</StackPanel>
<Canvas Grid.Row="1">
<Image x:Name="image" />
</Canvas>
</Grid>
</UserControl>
|