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 //* -------------------------------------------------------------------------------------------------
  • 相关阅读:
    MAIL (mailed 317 bytes of output but got status 0x004b#012)
    centOS7 复制文件夹
    X000100
    第一次博客作业
    《构建之法》阅读第四章、第十七章收获
    2016012017+小学四则运算练习软件项目报告
    看完构建之法1、2、16章的几个问题
    druid 多数据源配置
    flowableUI包
    vue 使用@fullcalendar进行行程展示
  • 原文地址:https://www.cnblogs.com/qiernonstop/p/3730241.html
Copyright © 2011-2022 走看看