silverligth 页面元素 保存成图片 以及独立存储

 先说说silverlight 的独立存储吧,和windows phone的独立存储概念一样,http://soft.zdnet.com.cn/software_zone/2009/0204/1332042.shtml 这篇文章写得非常好。
保存路径:C:\Users\v-jialia\AppData\LocalLow\Microsoft\Silverlight\is\j3lfxcgg.wes\3c5zew4w.pwg\1\s\22q1ww4utygitwusgxbr2pltyjvnx5scqrz3yvlhsvltkplyz2aaadba\f    独立存储所在的文件夹的位置是不是很隐蔽。。。

 

silverlight 保存成图片也和windows phone 非常类似,但是不是一个样。

private void button1_Click(object sender, RoutedEventArgs e)

        {

            ScaleTransform transform = new ScaleTransform();

            transform.ScaleX = 1;

            transform.ScaleY = 1;



            System.Windows.Media.Imaging.WriteableBitmap we = new System.Windows.Media.Imaging.WriteableBitmap( this, transform);

            

            Save(we);

        }



        private void Save(System.Windows.Media.Imaging.WriteableBitmap we)

        {



            var dlg = new SaveFileDialog();

            dlg.DefaultExt = ".png";

            dlg.Filter = "PNG File|*.png";



            EditableImage imageData = new EditableImage(we.PixelWidth, we.PixelHeight);

            try

            {

                for (int y = 0; y < we.PixelHeight; ++y)

                {

                    for (int x = 0; x < we.PixelWidth; ++x)

                    {

                        int pixel = we.Pixels[we.PixelWidth * y + x];

                        imageData.SetPixel(x, y,

                            (byte)((pixel >> 16) & 0xFF),

                            (byte)((pixel >> 8) & 0xFF),

                            (byte)(pixel & 0xFF), (byte)((pixel >> 24) & 0xFF)

                            );

                    }

                }

            }

            catch (Exception e)

            {



            }



            /*

            if (dlg.ShowDialog() == true)

            {

                

                Stream pngStream = imageData.GetStream();

                byte[] binaryData = new byte[pngStream.Length];

                pngStream.Read(binaryData,0,(int)pngStream.Length);

                Stream stream = dlg.OpenFile();

                stream.Write(binaryData,0,binaryData.Length);

                stream.Close();                



            }

            */



            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())

            {

                long newQuetaSize = 5242880*10;

                long curAvail = store.AvailableFreeSpace;



                if (curAvail < newQuetaSize)

                {

                    store.IncreaseQuotaTo(newQuetaSize*2);

                }



                string path = "graph reports.png";

                IsolatedStorageFileStream fileStream = store.CreateFile(path);

                Stream pngStream = imageData.GetStream();

                byte[] binaryData = new byte[pngStream.Length];

                pngStream.Read(binaryData, 0, (int)pngStream.Length);

                fileStream.Write(binaryData, 0, binaryData.Length);

                fileStream.Close();

            }

           



        }

    

这里要注意的一点是,有两个辅助类需要自己定义:

    /// <summary>

    /// PNG格式操作类

    /// </summary>

    public class PngEncoder

    {

        private const int _ADLER32_BASE = 65521;

        private const int _MAXBLOCK = 0xFFFF;

        private static byte[] _HEADER = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };

        private static byte[] _IHDR = { (byte)'I', (byte)'H', (byte)'D', (byte)'R' };

        private static byte[] _GAMA = { (byte)'g', (byte)'A', (byte)'M', (byte)'A' };

        private static byte[] _IDAT = { (byte)'I', (byte)'D', (byte)'A', (byte)'T' };

        private static byte[] _IEND = { (byte)'I', (byte)'E', (byte)'N', (byte)'D' };

        private static byte[] _4BYTEDATA = { 0, 0, 0, 0 };

        private static byte[] _ARGB = { 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 0, 0, 0 };



        /// <summary>

        /// 编码

        /// </summary>

        /// <param name="data"></param>

        /// <param name="width"></param>

        /// <param name="height"></param>

        /// <returns></returns>

        public static Stream Encode(byte[] data, int width, int height)

        {

            MemoryStream ms = new MemoryStream();

            byte[] size;



            // Write PNG header

            ms.Write(_HEADER, 0, _HEADER.Length);



            // Write IHDR

            //  Width:              4 bytes

            //  Height:             4 bytes

            //  Bit depth:          1 byte

            //  Color type:         1 byte

            //  Compression method: 1 byte

            //  Filter method:      1 byte

            //  Interlace method:   1 byte



            size = BitConverter.GetBytes(width);

            _ARGB[0] = size[3]; _ARGB[1] = size[2]; _ARGB[2] = size[1]; _ARGB[3] = size[0];



            size = BitConverter.GetBytes(height);

            _ARGB[4] = size[3]; _ARGB[5] = size[2]; _ARGB[6] = size[1]; _ARGB[7] = size[0];



            // Write IHDR chunk

            WriteChunk(ms, _IHDR, _ARGB);



            // Set gamma = 1

            size = BitConverter.GetBytes(1 * 100000);

            _4BYTEDATA[0] = size[3]; _4BYTEDATA[1] = size[2]; _4BYTEDATA[2] = size[1]; _4BYTEDATA[3] = size[0];



            // Write gAMA chunk

            WriteChunk(ms, _GAMA, _4BYTEDATA);



            // Write IDAT chunk

            uint widthLength = (uint)(width * 4) + 1;

            uint dcSize = widthLength * (uint)height;



            // First part of ZLIB header is 78 1101 1010 (DA) 0000 00001 (01)

            // ZLIB info

            //

            // CMF Byte: 78

            //  CINFO = 7 (32K window size)

            //  CM = 8 = (deflate compression)

            // FLG Byte: DA

            //  FLEVEL = 3 (bits 6 and 7 - ignored but signifies max compression)

            //  FDICT = 0 (bit 5, 0 - no preset dictionary)

            //  FCHCK = 26 (bits 0-4 - ensure CMF*256+FLG / 31 has no remainder)

            // Compressed data

            //  FLAGS: 0 or 1

            //    00000 00 (no compression) X (X=1 for last block, 0=not the last block)

            //    LEN = length in bytes (equal to ((width*4)+1)*height

            //    NLEN = one's compliment of LEN

            //    Example: 1111 1011 1111 1111 (FB), 0000 0100 0000 0000 (40)

            //    Data for each line: 0 [RGBA] [RGBA] [RGBA] ...

            //    ADLER32



            uint adler = ComputeAdler32(data);

            MemoryStream comp = new MemoryStream();



            // 64K的块数计算

            uint rowsPerBlock = _MAXBLOCK / widthLength;

            uint blockSize = rowsPerBlock * widthLength;

            uint blockCount;

            ushort length;

            uint remainder = dcSize;



            if ((dcSize % blockSize) == 0)

            {

                blockCount = dcSize / blockSize;

            }

            else

            {

                blockCount = (dcSize / blockSize) + 1;

            }



            // 头部

            comp.WriteByte(0x78);

            comp.WriteByte(0xDA);



            for (uint blocks = 0; blocks < blockCount; blocks++)

            {

                // 长度

                length = (ushort)((remainder < blockSize) ? remainder : blockSize);



                if (length == remainder)

                {

                    comp.WriteByte(0x01);

                }

                else

                {

                    comp.WriteByte(0x00);

                }



                comp.Write(BitConverter.GetBytes(length), 0, 2);



                comp.Write(BitConverter.GetBytes((ushort)~length), 0, 2);



                // Write 块

                comp.Write(data, (int)(blocks * blockSize), length);



                //下一块

                remainder -= blockSize;

            }



            WriteReversedBuffer(comp, BitConverter.GetBytes(adler));

            comp.Seek(0, SeekOrigin.Begin);



            byte[] dat = new byte[comp.Length];

            comp.Read(dat, 0, (int)comp.Length);



            WriteChunk(ms, _IDAT, dat);



            // Write IEND chunk

            WriteChunk(ms, _IEND, new byte[0]);



            // Reset stream

            ms.Seek(0, SeekOrigin.Begin);



            return ms;

        }



        private static void WriteReversedBuffer(Stream stream, byte[] data)

        {

            int size = data.Length;

            byte[] reorder = new byte[size];



            for (int idx = 0; idx < size; idx++)

            {

                reorder[idx] = data[size - idx - 1];

            }

            stream.Write(reorder, 0, size);

        }



        private static void WriteChunk(Stream stream, byte[] type, byte[] data)

        {

            int idx;

            int size = type.Length;

            byte[] buffer = new byte[type.Length + data.Length];



            // 初始化缓冲

            for (idx = 0; idx < type.Length; idx++)

            {

                buffer[idx] = type[idx];

            }



            for (idx = 0; idx < data.Length; idx++)

            {

                buffer[idx + size] = data[idx];

            }



            WriteReversedBuffer(stream, BitConverter.GetBytes(data.Length));



            // Write 类型和数据

            stream.Write(buffer, 0, buffer.Length);   // Should always be 4 bytes



            // 计算和书写的CRC



            WriteReversedBuffer(stream, BitConverter.GetBytes(GetCRC(buffer)));

        }



        private static uint[] _crcTable = new uint[256];

        private static bool _crcTableComputed = false;



        private static void MakeCRCTable()

        {

            uint c;



            for (int n = 0; n < 256; n++)

            {

                c = (uint)n;

                for (int k = 0; k < 8; k++)

                {

                    if ((c & (0x00000001)) > 0)

                        c = 0xEDB88320 ^ (c >> 1);

                    else

                        c = c >> 1;

                }

                _crcTable[n] = c;

            }



            _crcTableComputed = true;

        }



        private static uint UpdateCRC(uint crc, byte[] buf, int len)

        {

            uint c = crc;



            if (!_crcTableComputed)

            {

                MakeCRCTable();

            }



            for (int n = 0; n < len; n++)

            {

                c = _crcTable[(c ^ buf[n]) & 0xFF] ^ (c >> 8);

            }



            return c;

        }



        //返回的字节的CRC缓冲区

        private static uint GetCRC(byte[] buf)

        {

            return UpdateCRC(0xFFFFFFFF, buf, buf.Length) ^ 0xFFFFFFFF;

        }



        private static uint ComputeAdler32(byte[] buf)

        {

            uint s1 = 1;

            uint s2 = 0;

            int length = buf.Length;



            for (int idx = 0; idx < length; idx++)

            {

                s1 = (s1 + (uint)buf[idx]) % _ADLER32_BASE;

                s2 = (s2 + s1) % _ADLER32_BASE;

            }



            return (s2 << 16) + s1;

        }

    }



    /// <summary>

    /// 编辑图片

    /// </summary>

    public class EditableImage

    {

        private int _width = 0;

        private int _height = 0;

        private bool _init = false;

        private byte[] _buffer;

        private int _rowLength;



        /// <summary>

        /// 当图片错误时引发

        /// </summary>

        public event EventHandler<EditableImageErrorEventArgs> ImageError;



        /// <summary>

        /// 实例化

        /// </summary>

        /// <param name="width"></param>

        /// <param name="height"></param>

        public EditableImage(int width, int height)

        {

            this.Width = width;

            this.Height = height;

        }



        public int Width

        {

            get

            {

                return _width;

            }

            set

            {

                if (_init)

                {

                    OnImageError("错误: 图片初始化后不可以改变宽度");

                }

                else if ((value <= 0) || (value > 2047))

                {

                    OnImageError("错误: 宽度必须在 0 到 2047");

                }

                else

                {

                    _width = value;

                }

            }

        }



        public int Height

        {

            get

            {

                return _height;

            }

            set

            {

                if (_init)

                {

                    OnImageError("错误: 图片初始化后不可以改变高度");

                }

                else if ((value <= 0) || (value > 2047))

                {

                    OnImageError("错误: 高度必须在 0 到 2047");

                }

                else

                {

                    _height = value;

                }

            }

        }



        public void SetPixel(int col, int row, Color color)

        {

            SetPixel(col, row, color.R, color.G, color.B, color.A);

        }



        public void SetPixel(int col, int row, byte red, byte green, byte blue, byte alpha)

        {

            if (!_init)

            {

                _rowLength = _width * 4 + 1;

                _buffer = new byte[_rowLength * _height];



                // Initialize

                for (int idx = 0; idx < _height; idx++)

                {

                    _buffer[idx * _rowLength] = 0;      // Filter bit

                }



                _init = true;

            }



            if ((col > _width) || (col < 0))

            {

                OnImageError("Error: Column must be greater than 0 and less than the Width");

            }

            else if ((row > _height) || (row < 0))

            {

                OnImageError("Error: Row must be greater than 0 and less than the Height");

            }



            // Set the pixel

            int start = _rowLength * row + col * 4 + 1;

            _buffer[start] = red;

            _buffer[start + 1] = green;

            _buffer[start + 2] = blue;

            _buffer[start + 3] = alpha;

        }



        public Color GetPixel(int col, int row)

        {

            if ((col > _width) || (col < 0))

            {

                OnImageError("Error: Column must be greater than 0 and less than the Width");

            }

            else if ((row > _height) || (row < 0))

            {

                OnImageError("Error: Row must be greater than 0 and less than the Height");

            }



            Color color = new Color();

            int _base = _rowLength * row + col + 1;



            color.R = _buffer[_base];

            color.G = _buffer[_base + 1];

            color.B = _buffer[_base + 2];

            color.A = _buffer[_base + 3];



            return color;

        }



        public Stream GetStream()

        {

            Stream stream;



            if (!_init)

            {

                OnImageError("Error: Image has not been initialized");

                stream = null;

            }

            else

            {

                stream = PngEncoder.Encode(_buffer, _width, _height);

            }



            return stream;

        }



        private void OnImageError(string msg)

        {

            if (null != ImageError)

            {

                EditableImageErrorEventArgs args = new EditableImageErrorEventArgs();

                args.ErrorMessage = msg;

                ImageError(this, args);

            }

        }



        public class EditableImageErrorEventArgs : EventArgs

        {

            private string _errorMessage = string.Empty;



            public string ErrorMessage

            {

                get { return _errorMessage; }

                set { _errorMessage = value; }

            }

        }



    }

有一个很大的问题暂时没法解决: 当网页超过屏幕长度时,截出来的图也是最多只有一个屏幕大小,而不会把滚动条内的内容都显示出来。

你可能感兴趣的:(图片)