
1、EditableImage.cs类,代码如下:
using System;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.Ink;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using System.IO;namespace MapClIEnt.CommonClass{ public class EditableImage { private int _wIDth = 0; private int _height = 0; private bool _init = false; private byte[] _buffer; private int _rowLength; public event EventHandler<EditableImageErrorEventArgs> ImageError; public EditableImage(int wIDth,int height) { this.WIDth = wIDth; this.Height = height; } public int WIDth { get { return _wIDth; } set { if (_init) { OnImageError("Error: Cannot change WIDth after the EditableImage has been initialized"); } else if ((value <= 0) || (value > 2047)) { OnImageError("Error: WIDth must be between 0 and 2047"); } else { _wIDth = value; } } } public int Height { get { return _height; } set { if (_init) { OnImageError("Error: Cannot change Height after the EditableImage has been initialized"); } else if ((value <= 0) || (value > 2047)) { OnImageError("Error: Height must be between 0 and 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,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; } } } }} 2、ElementtopNG.cs类,代码如下:
using System;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.Ink;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using System.windows.Media.Imaging;using System.IO;namespace MapClIEnt.CommonClass{ /// <summary> /// Based on: /// /// Andy BeaulIEu /// http://www.andybeaulIEu.com/Home/tabID/67/EntryID/161/Default.aspx /// /// /// Tom Giam /// http://silverlight.net/forums/t/108713.aspx /// </summary> public class ElementtopNG { public voID ShowSaveDialog(UIElement elementToExport) { //Canvas canvasToExport = e as Canvas; // Instantiate SavefileDialog // and set defautl settings (just PNG export) SavefileDialog sfd = new SavefileDialog() { DefaultExt = "png",Filter = "Png files (*.png)|*.png|All files (*.*)|*.*",FilterIndex = 1 }; if (sfd.ShowDialog() == true) { SaveAsPNG(sfd,elementToExport); } } private voID SaveAsPNG(SavefileDialog sfd,UIElement elementToExport) { WriteableBitmap bitmap = new WriteableBitmap(elementToExport,new Translatetransform()); EditableImage imageData = new EditableImage(bitmap.PixelWIDth,bitmap.PixelHeight); try { for (int y = 0; y < bitmap.PixelHeight; ++y) { for (int x = 0; x < bitmap.PixelWIDth; ++x) { int pixel = bitmap.Pixels[bitmap.PixelWIDth * y + x]; imageData.SetPixel(x,y,(byte)((pixel >> 16) & 0xFF),(byte)((pixel >> 8) & 0xFF),(byte)(pixel & 0xFF),(byte)((pixel >> 24) & 0xFF) ); } } } catch (System.Security.SecurityException) { throw new Exception("Cannot print images from other domains"); } // Save it to disk Stream pngStream = imageData.GetStream(); //StreamReader sr = new StreamReader(pngStream); byte[] binaryData = new Byte[pngStream.Length]; long bytesRead = pngStream.Read(binaryData,(int)pngStream.Length); //using (Stream stream = sfd.Openfile()) //{ // stream.Write(binaryData,binaryData.Length); // stream.Close(); //} Stream stream = sfd.Openfile(); stream.Write(binaryData,binaryData.Length); stream.Close(); } }} using System;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.Ink;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;using System.IO;using System.windows.browser;using System.Reflection;namespace MapClIEnt.CommonClass{ 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)'T' }; private static byte[] _IEND = { (byte)'I',(byte)'E',(byte)'N',(byte)'D' }; private static byte[] _4BYTEDATA = { 0,0 }; private static byte[] _ARGB = { 0,8,6,0 }; public static Stream Encode(byte[] data,int wIDth,int height) { MemoryStream ms = new MemoryStream(); byte[] size; // Write PNG header ms.Write(_header,_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(); // Calculate number of 64K blocks 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; } // Write headers comp.WriteByte(0x78); comp.WriteByte(0xDA); for (uint blocks = 0; blocks < blockCount; blocks++) { // Write LEN length = (ushort)((remainder < blockSize) ? remainder : blockSize); if (length == remainder) { comp.WriteByte(0x01); } else { comp.WriteByte(0x00); } comp.Write(BitConverter.GetBytes(length),2); // Write one's compliment of LEN comp.Write(BitConverter.GetBytes((ushort)~length),2); // Write blocks comp.Write(data,(int)(blocks * blockSize),length); // Next block remainder -= blockSize; } WriteReversedBuffer(comp,BitConverter.GetBytes(adler)); comp.Seek(0,SeekOrigin.Begin); byte[] dat = new byte[comp.Length]; comp.Read(dat,(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; // See http://www.libpng.org/pub/png//spec/1.2/PNG-Chunks.HTML // See http://www.libpng.org/pub/png/book/chapter08.HTML#png.ch08.div.4 // See http://www.gzip.org/zlib/rfc-zlib.HTML (ZliB format) // See ftp://ftp.uu.net/pub/archiving/zip/doc/rfc1951.txt (ZliB compression format) } 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,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]; // Initialize buffer for (IDx = 0; IDx < type.Length; IDx++) { buffer[IDx] = type[IDx]; } for (IDx = 0; IDx < data.Length; IDx++) { buffer[IDx + size] = data[IDx]; } // Write length WriteReversedBuffer(stream,BitConverter.GetBytes(data.Length)); // Write type and data stream.Write(buffer,buffer.Length); // Should always be 4 bytes // Compute and write the 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; } /* Return the CRC of the bytes buf[0..len-1]. */ 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; } }} 总结 以上是内存溢出为你收集整理的Silverlight导出图片需要的几个类全部内容,希望文章能够帮你解决Silverlight导出图片需要的几个类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)