跟小D每日学口语

Determine PixelWidth and PixelHeight for JPEG image in Silverlight 2B1

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>

posted @ 2009-02-04 20:17  javak  阅读(355)  评论(0)    收藏  举报