Silverlight导出图片需要的几个类

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, 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; }
            }
        }

    }
}

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, 0, (int)pngStream.Length);

            //using (Stream stream = sfd.OpenFile())
            //{

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

            //    stream.Close();

            //}

            Stream stream = sfd.OpenFile();

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

            stream.Close();

        }
    }
}

3、PngEncoder.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;
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)‘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 };

        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();

            // 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), 0, 2);

                // Write one‘s compliment of LEN
                comp.Write(BitConverter.GetBytes((ushort)~length), 0, 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, 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;

            // 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, 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];

            // 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, 0, 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;
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 04:19:31

Silverlight导出图片需要的几个类的相关文章

highcharts 导出图片 .net Demo

highcharts 的Net导出服务  GitHub上整理的https://github.com/imclem/Highcharts-export-module-asp.net 引用两个程序集 sharpPDF.dll,Svg.dll (实际上就是将svg转化成其他格式的图片) 两种导出情况:   1.只需要图片,修改自带导出按钮的请求路径路径就行2.需要插入到word等二次处理再导出时 页面: @{ ViewBag.Title = "Index"; } @section css{

PHP Excel表格导出图片方法

1.进入PHP Excel官网后,找到右边的download按钮,下载,下载完成的是一个压缩文件,解压放到你的项目目录里. 2.查看解压文件是否有PHPExcel_Worksheet_Drawing图片文件类. 3.创建一个excel.php文件,开始编写PHP Excel到出. 实例代码: <?php /** * PHP Excel表格导出图片方法 * 2015-07-30 巴亚云 */ function ExcelCustomers(){ /*引入phpexcel核心类文件*/ includ

Excel催化剂开源第45波-按原图大小导出图片

从Excel中导出图片,是一个很常规的需求,也有一些久旧不衰的界面操作法小技巧从OpenXml文件中批量导出,在VBA开发中,也会使用Chart对象的背景图的技巧来导出.总体来说,和真正想要的效果还是有差距,特别是这样的方式导出的图片像素会低. 在VSTO开发中,有更好的方式,此篇给大家一一分享. 使用Excel催化剂的插入图片的方式,图片已经存储在PictureBox容器内,想导出时,只需在PictureBox容器上取出其Image属性,即可拿到图片,再简单的一个保存为文件的方法即可完成. 以

keynote如何无损导出图片?怎么把图片导出来

在做工作汇报的时候,keynote是我们经常使用的工具,里面会有很多我们用的上的图片素材,那么keynote如何无损导出图片?如何在不丢失画质的情况导出这些图片呢,小编总结了具体的步骤,可以帮您完成这个问题,如果你get了就可以快速导出他们了哦!下面看看具体是如何操作的吧! keynote无损导出图片步骤: 第一步:选中图片 第二步:选择"格式"-"图像" 第三步:在右侧属性栏右上角的位置,将会出现"文件信息",里面包含了这张图片的jpeg图标以

fusioncharts批量导出图片之后自动提交表单

最近一个项目  一个页面有多个fusioncharts,需要将他们一次性导出之后再利用图片做一下操作,制作一个可以客户下载的质检简报. 对客户效果来说,我只需要点击一个按钮就能生成简报并且下载,对开发人员来说就需要,先将图片导出(当然不能挨个导出,要同时执行导出,因为fusioncharts导出太慢了),要确认全部导出了才能提交表单,要不然提交表单之后,图片没有生成出来必然产生异常.下面我们来看一下实现 首先我给每一个fusionchartschart指定一个有规律的id,作用有两个: 一个是导

Highcharts使用phantomjs导出图片

Highcharts使用phantomjs导出图片 ?Highcharts使用phantomjs导出图片 描述 在用Highcharts这个强大的图标组件时,你一定在某些时刻想把画出来的图标导出为一个图片并下载到本地.Highcharts本身提供了导出功能,只需要导入exporting.js文件,就可以在图表右上角找到导出按钮了.这已经基本满足的大多数情况我们的需求.但是这原始到导出是发送请求到Highcharts的服务器上进行转化的,很多时候我们并不想把我们的数据信息暴露给他们,所以我们必须在

Highcharts导出图片

概述: Highcharts是在做项目涉及到统计图的时候大家的首选,同时也会用到highcharts的export功能,将统计图导出为图片,刚好,最近也遇到了这样的事情,总结出来,以备后用. 导出方式: highcharts导出图片实现有三种:highcharts服务器导出.局域网服务器导出.本地后台导出. 首先,highcharts服务器导出是默认的导出方式,不需要任何操作,只需在chart中配置export参数即可,但是这种导出方式需要联网: 其次,局域网服务器导出,需要在局域网内配置导出的

Highcharts 本地导出图片 Java

下载的 Highcharts-2.3.5.zip 解压后 有 E:\Highcharts\Highcharts-2.3.5\exporting-server\java 目录 提供了Java实现的导出应用. 1)安装maven,配置环境变量. (http://maven.apache.org/download.cgi)  1.jdk 我装的是E:\java\jdk\jdk1.6.0_02-windows.exe  2.我的电脑-----属性----高级-----环境变量-----环境变量-----

Fusioncharts的导出图片訪问官网问题

Fusioncharts3.5使用自带的导出功能,须要訪问官网 问题描写叙述:使用fusioncharts自带的exportchart方法来导出图片的时候.要訪问export.api3.fusioncharts.com, 为此.因为任务量的大小或者网络性能的原因.或者局域网的限制性导致了下载图片不全或者不能訪问server的 server报504的错误. 解决方式:通过在Fusioncharts.js文件里搜索export.api3.fusioncharts.com发现,它的导出图片的功能,的确