zoukankan      html  css  js  c++  java
  • silverlight导出图片文件

    新建一个Silverlight应用程序,添加下面两个控件:

    image控件:image1;

    Button控件:Click="Button1_Click";

    code-Behind代码如下:

    1         private void Button1_Click(object sender, RoutedEventArgs e)
    2         {
    3             ElementToPNG eTP = new ElementToPNG();
    4             eTP.ShowSaveDialog(image1);
    5         }

    并添加下面三个类:

      1 //* -------------------------------------------------------------------------------------------------
      2 //* 下面的三个类是处理图片导出的
      3 //* -------------------------------------------------------------------------------------------------
      4 # region Class ElementToPNG
      5     public class ElementToPNG
      6     {
      7         public void ShowSaveDialog(UIElement elementToExport)
      8         {
      9             SaveFileDialog sfd = new SaveFileDialog()
     10             {
     11                 DefaultExt = "png",
     12                 Filter = "Png files (*.png)|*.png|All files (*.*)|*.*",
     13                 FilterIndex = 1
     14             };
     15 
     16             if (sfd.ShowDialog() == true)
     17             {
     18                 SaveAsPNG(sfd, elementToExport);
     19             }
     20         }
     21         private void SaveAsPNG(SaveFileDialog sfd, UIElement elementToExport)
     22         {
     23             WriteableBitmap bitmap = new WriteableBitmap(elementToExport, new TranslateTransform());
     24             EditableImage imageData = new EditableImage(bitmap.PixelWidth, bitmap.PixelHeight);
     25             try
     26             {
     27                 for (int y = 0; y < bitmap.PixelHeight; ++y)
     28                 {
     29                     for (int x = 0; x < bitmap.PixelWidth; ++x)
     30                     {
     31                         int pixel = bitmap.Pixels[bitmap.PixelWidth * y + x];
     32                         imageData.SetPixel(x, y,
     33                         (byte)((pixel >> 16) & 0xFF),
     34                         (byte)((pixel >> 8) & 0xFF),
     35                         (byte)(pixel & 0xFF), (byte)((pixel >> 24) & 0xFF)
     36                         );
     37                     }
     38                 }
     39             }
     40             catch (System.Security.SecurityException)
     41             {
     42                 throw new Exception("Cannot print images from other domains");
     43             }
     44             Stream pngStream = imageData.GetStream();
     45             byte[] binaryData = new Byte[pngStream.Length];
     46             long bytesRead = pngStream.Read(binaryData, 0, (int)pngStream.Length);
     47             Stream stream = sfd.OpenFile();
     48             stream.Write(binaryData, 0, binaryData.Length);
     49             stream.Close();
     50         }
     51     }
     52 # endregion
     53 
     54 # region Class EditableImage
     55     public class EditableImage
     56     {
     57         private int _width = 0;
     58         private int _height = 0;
     59         private bool _init = false;
     60         private byte[] _buffer;
     61         private int _rowLength;
     62 
     63         public event EventHandler<EditableImageErrorEventArgs> ImageError;
     64 
     65         public EditableImage(int width, int height)
     66         {
     67             this.Width = width;
     68             this.Height = height;
     69         }
     70 
     71         public int Width
     72         {
     73             get
     74             {
     75                 return _width;
     76             }
     77             set
     78             {
     79                 if (_init)
     80                 {
     81                     OnImageError("Error: Cannot change Width after the EditableImage has been initialized");
     82                 }
     83                 else if ((value <= 0) || (value > 2047))
     84                 {
     85                     OnImageError("Error: Width must be between 0 and 2047");
     86                 }
     87                 else
     88                 {
     89                     _width = value;
     90                 }
     91             }
     92         }
     93 
     94         public int Height
     95         {
     96             get
     97             {
     98                 return _height;
     99             }
    100             set
    101             {
    102                 if (_init)
    103                 {
    104                     OnImageError("Error: Cannot change Height after the EditableImage has been initialized");
    105                 }
    106                 else if ((value <= 0) || (value > 2047))
    107                 {
    108                     OnImageError("Error: Height must be between 0 and 2047");
    109                 }
    110                 else
    111                 {
    112                     _height = value;
    113                 }
    114             }
    115         }
    116 
    117         public void SetPixel(int col, int row, Color color)
    118         {
    119             SetPixel(col, row, color.R, color.G, color.B, color.A);
    120         }
    121 
    122         public void SetPixel(int col, int row, byte red, byte green, byte blue, byte alpha)
    123         {
    124             if (!_init)
    125             {
    126                 _rowLength = _width * 4 + 1;
    127                 _buffer = new byte[_rowLength * _height];
    128 
    129                 // Initialize
    130                 for (int idx = 0; idx < _height; idx++)
    131                 {
    132                     _buffer[idx * _rowLength] = 0;      // Filter bit
    133                 }
    134 
    135                 _init = true;
    136             }
    137 
    138             if ((col > _width) || (col < 0))
    139             {
    140                 OnImageError("Error: Column must be greater than 0 and less than the Width");
    141             }
    142             else if ((row > _height) || (row < 0))
    143             {
    144                 OnImageError("Error: Row must be greater than 0 and less than the Height");
    145             }
    146 
    147             // Set the pixel
    148             int start = _rowLength * row + col * 4 + 1;
    149             _buffer[start] = red;
    150             _buffer[start + 1] = green;
    151             _buffer[start + 2] = blue;
    152             _buffer[start + 3] = alpha;
    153         }
    154 
    155         public Color GetPixel(int col, int row)
    156         {
    157             if ((col > _width) || (col < 0))
    158             {
    159                 OnImageError("Error: Column must be greater than 0 and less than the Width");
    160             }
    161             else if ((row > _height) || (row < 0))
    162             {
    163                 OnImageError("Error: Row must be greater than 0 and less than the Height");
    164             }
    165 
    166             Color color = new Color();
    167             int _base = _rowLength * row + col + 1;
    168 
    169             color.R = _buffer[_base];
    170             color.G = _buffer[_base + 1];
    171             color.B = _buffer[_base + 2];
    172             color.A = _buffer[_base + 3];
    173 
    174             return color;
    175         }
    176 
    177         public Stream GetStream()
    178         {
    179             Stream stream;
    180 
    181             if (!_init)
    182             {
    183                 OnImageError("Error: Image has not been initialized");
    184                 stream = null;
    185             }
    186             else
    187             {
    188                 stream = PngEncoder.Encode(_buffer, _width, _height);
    189             }
    190 
    191             return stream;
    192         }
    193 
    194         private void OnImageError(string msg)
    195         {
    196             if (null != ImageError)
    197             {
    198                 EditableImageErrorEventArgs args = new EditableImageErrorEventArgs();
    199                 args.ErrorMessage = msg;
    200                 ImageError(this, args);
    201             }
    202         }
    203 
    204         public class EditableImageErrorEventArgs : EventArgs
    205         {
    206             private string _errorMessage = string.Empty;
    207 
    208             public string ErrorMessage
    209             {
    210                 get { return _errorMessage; }
    211                 set { _errorMessage = value; }
    212             }
    213         }
    214 
    215     }
    216 # endregion
    217 
    218 # region Class PngEncoder
    219     public class PngEncoder
    220     {
    221         private const int _ADLER32_BASE = 65521;
    222         private const int _MAXBLOCK = 0xFFFF;
    223         private static byte[] _HEADER = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
    224         private static byte[] _IHDR = { (byte)'I', (byte)'H', (byte)'D', (byte)'R' };
    225         private static byte[] _GAMA = { (byte)'g', (byte)'A', (byte)'M', (byte)'A' };
    226         private static byte[] _IDAT = { (byte)'I', (byte)'D', (byte)'A', (byte)'T' };
    227         private static byte[] _IEND = { (byte)'I', (byte)'E', (byte)'N', (byte)'D' };
    228         private static byte[] _4BYTEDATA = { 0, 0, 0, 0 };
    229         private static byte[] _ARGB = { 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 0, 0, 0 };
    230 
    231 
    232         public static Stream Encode(byte[] data, int width, int height)
    233         {
    234             MemoryStream ms = new MemoryStream();
    235             byte[] size;
    236 
    237             // Write PNG header
    238             ms.Write(_HEADER, 0, _HEADER.Length);
    239 
    240             size = BitConverter.GetBytes(width);
    241             _ARGB[0] = size[3]; _ARGB[1] = size[2]; _ARGB[2] = size[1]; _ARGB[3] = size[0];
    242 
    243             size = BitConverter.GetBytes(height);
    244             _ARGB[4] = size[3]; _ARGB[5] = size[2]; _ARGB[6] = size[1]; _ARGB[7] = size[0];
    245 
    246             // Write IHDR chunk
    247             WriteChunk(ms, _IHDR, _ARGB);
    248 
    249             // Set gamma = 1
    250             size = BitConverter.GetBytes(1 * 100000);
    251             _4BYTEDATA[0] = size[3]; _4BYTEDATA[1] = size[2]; _4BYTEDATA[2] = size[1]; _4BYTEDATA[3] = size[0];
    252 
    253             // Write gAMA chunk
    254             WriteChunk(ms, _GAMA, _4BYTEDATA);
    255 
    256             // Write IDAT chunk
    257             uint widthLength = (uint)(width * 4) + 1;
    258             uint dcSize = widthLength * (uint)height;
    259 
    260             uint adler = ComputeAdler32(data);
    261             MemoryStream comp = new MemoryStream();
    262 
    263             // Calculate number of 64K blocks
    264             uint rowsPerBlock = _MAXBLOCK / widthLength;
    265             uint blockSize = rowsPerBlock * widthLength;
    266             uint blockCount;
    267             ushort length;
    268             uint remainder = dcSize;
    269 
    270             if ((dcSize % blockSize) == 0)
    271             {
    272                 blockCount = dcSize / blockSize;
    273             }
    274             else
    275             {
    276                 blockCount = (dcSize / blockSize) + 1;
    277             }
    278 
    279             // Write headers
    280             comp.WriteByte(0x78);
    281             comp.WriteByte(0xDA);
    282 
    283             for (uint blocks = 0; blocks < blockCount; blocks++)
    284             {
    285                 // Write LEN
    286                 length = (ushort)((remainder < blockSize) ? remainder : blockSize);
    287 
    288                 if (length == remainder)
    289                 {
    290                     comp.WriteByte(0x01);
    291                 }
    292                 else
    293                 {
    294                     comp.WriteByte(0x00);
    295                 }
    296 
    297                 comp.Write(BitConverter.GetBytes(length), 0, 2);
    298 
    299                 // Write one's compliment of LEN
    300                 comp.Write(BitConverter.GetBytes((ushort)~length), 0, 2);
    301 
    302                 // Write blocks
    303                 comp.Write(data, (int)(blocks * blockSize), length);
    304 
    305                 // Next block
    306                 remainder -= blockSize;
    307             }
    308 
    309             WriteReversedBuffer(comp, BitConverter.GetBytes(adler));
    310             comp.Seek(0, SeekOrigin.Begin);
    311 
    312             byte[] dat = new byte[comp.Length];
    313             comp.Read(dat, 0, (int)comp.Length);
    314 
    315             WriteChunk(ms, _IDAT, dat);
    316 
    317             // Write IEND chunk
    318             WriteChunk(ms, _IEND, new byte[0]);
    319 
    320             // Reset stream
    321             ms.Seek(0, SeekOrigin.Begin);
    322 
    323             return ms;
    324         }
    325 
    326         private static void WriteReversedBuffer(Stream stream, byte[] data)
    327         {
    328             int size = data.Length;
    329             byte[] reorder = new byte[size];
    330 
    331             for (int idx = 0; idx < size; idx++)
    332             {
    333                 reorder[idx] = data[size - idx - 1];
    334             }
    335             stream.Write(reorder, 0, size);
    336         }
    337 
    338         private static void WriteChunk(Stream stream, byte[] type, byte[] data)
    339         {
    340             int idx;
    341             int size = type.Length;
    342             byte[] buffer = new byte[type.Length + data.Length];
    343 
    344             // Initialize buffer
    345             for (idx = 0; idx < type.Length; idx++)
    346             {
    347                 buffer[idx] = type[idx];
    348             }
    349 
    350             for (idx = 0; idx < data.Length; idx++)
    351             {
    352                 buffer[idx + size] = data[idx];
    353             }
    354 
    355             // Write length
    356             WriteReversedBuffer(stream, BitConverter.GetBytes(data.Length));
    357 
    358             // Write type and data
    359             stream.Write(buffer, 0, buffer.Length);   // Should always be 4 bytes
    360 
    361             // Compute and write the CRC
    362             WriteReversedBuffer(stream, BitConverter.GetBytes(GetCRC(buffer)));
    363         }
    364         private static uint[] _crcTable = new uint[256];
    365         private static bool _crcTableComputed = false;
    366         private static void MakeCRCTable()
    367         {
    368             uint c;
    369             for (int n = 0; n < 256; n++)
    370             {
    371                 c = (uint)n;
    372                 for (int k = 0; k < 8; k++)
    373                 {
    374                     if ((c & (0x00000001)) > 0)
    375                         c = 0xEDB88320 ^ (c >> 1);
    376                     else
    377                         c = c >> 1;
    378                 }
    379                 _crcTable[n] = c;
    380             }
    381 
    382             _crcTableComputed = true;
    383         }
    384         private static uint UpdateCRC(uint crc, byte[] buf, int len)
    385         {
    386             uint c = crc;
    387 
    388             if (!_crcTableComputed)
    389             {
    390                 MakeCRCTable();
    391             }
    392 
    393             for (int n = 0; n < len; n++)
    394             {
    395                 c = _crcTable[(c ^ buf[n]) & 0xFF] ^ (c >> 8);
    396             }
    397 
    398             return c;
    399         }
    400         private static uint GetCRC(byte[] buf)
    401         {
    402             return UpdateCRC(0xFFFFFFFF, buf, buf.Length) ^ 0xFFFFFFFF;
    403         }
    404         private static uint ComputeAdler32(byte[] buf)
    405         {
    406             uint s1 = 1;
    407             uint s2 = 0;
    408             int length = buf.Length;
    409 
    410             for (int idx = 0; idx < length; idx++)
    411             {
    412                 s1 = (s1 + (uint)buf[idx]) % _ADLER32_BASE;
    413                 s2 = (s2 + s1) % _ADLER32_BASE;
    414             }
    415             return (s2 << 16) + s1;
    416         }
    417     }
    418 # endregion
    419 //* -------------------------------------------------------------------------------------------------
    420 //* -------------------------------------------------------------------------------------------------
  • 相关阅读:
    (转)【web前端培训之前后端的配合(中)】继续昨日的故事
    ural(Timus) 1136. Parliament
    scau Josephus Problem
    ACMICPC Live Archive 6204 Poker End Games
    uva 10391 Compound Words
    ACMICPC Live Archive 3222 Joke with Turtles
    uva 10132 File Fragmentation
    uva 270 Lining Up
    【转】各种字符串哈希函数比较
    uva 10905 Children's Game
  • 原文地址:https://www.cnblogs.com/qiernonstop/p/3730241.html
Copyright © 2011-2022 走看看