首页 > 代码库 > C# 转换图形为PCX 格式

C# 转换图形为PCX 格式

2010-5-27

PCX RLE压缩图形的行对齐比.NET多了一位.已经修正了.

 

2009 -7-25

C# 转换图形为PCX 格式 增加了对1位色的PCX的读取

 

2009-6 -12

RLE数据压缩更改 颜色RGB在RLE压缩不换行处理.....

 

 

.NET 支持的格式..保存成PCX格式..

目前只支持两种结果 256色图  和24位图... 其他位的以后在说把..

 

使用方法

 

  Zgke.MyImage.ImageFile.ImagePcx _Pcx = new Zgke.MyImage.ImageFile.ImagePcx();
            _Pcx.PcxImage = this.Icon.ToBitmap();
            _Pcx.Save(@"C:/1.pcx");

 

如果你看这篇文章...上篇

 

 http://blog.csdn.net/zgke/archive/2009/05/19/4201621.aspx C#解析PCX图形文件

可以忽略了.下面的代码包含读和保存的功能..目前能保存256色图 和24位图..如果你的图形不是这两种 ..代码里把你的图形复制成24位的图 .然后去保存..

 

全部代码...

 

[c-sharp] view plaincopy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Drawing;  
  5. using System.Drawing.Imaging;  
  6. using System.IO;  
  7. using System.Runtime.InteropServices;  
  8.   
  9. namespace Zgke.MyImage.ImageFile  
  10. {  
  11.     /// <summary>  
  12.     /// PCX操作类  
  13.     /// zgke@sina.com  
  14.     /// qq:116149  
  15.     /// </summary>  
  16.     public class ImagePcx  
  17.     {  
  18.         /// <summary>  
  19.         /// PCX文件头  
  20.         /// </summary>  
  21.         private class PCXHEAD  
  22.         {  
  23.             public byte[] m_Data = new byte[128];  
  24.   
  25.             /// <summary>  
  26.             /// 文件头必须为 0A;  
  27.             /// </summary>  
  28.             public byte Manufacturer { get { return m_Data[0]; } }  
  29.             /// <summary>  
  30.             /// 0:PC Paintbrush 2.5 版   2:PC Paintbrush 2.8 版  5:PC Paintbrush 3.0 版  
  31.             /// </summary>  
  32.             public byte Version { get { return m_Data[1]; } set { m_Data[1] = value; } }  
  33.             /// <summary>  
  34.             /// 其值为1时表示采用RLE压缩编码的方法  
  35.             /// </summary>  
  36.             public byte Encoding { get { return m_Data[2]; } set { m_Data[2] = value; } }  
  37.             /// <summary>  
  38.             /// 每个相素的位数  
  39.             /// </summary>  
  40.             public byte Bits_Per_Pixel { get { return m_Data[3]; } set { m_Data[3] = value; } }  
  41.   
  42.             public ushort Xmin { get { return BitConverter.ToUInt16(m_Data, 4); } set { SetUshort(4, value); } }  
  43.             public ushort Ymin { get { return BitConverter.ToUInt16(m_Data, 6); } set { SetUshort(6, value); } }  
  44.             public ushort Xmax { get { return BitConverter.ToUInt16(m_Data, 8); } set { SetUshort(8, value); } }  
  45.             public ushort Ymax { get { return BitConverter.ToUInt16(m_Data, 10); } set { SetUshort(10, value); } }  
  46.             /// <summary>  
  47.             /// 水平分辨率  
  48.             /// </summary>  
  49.             public ushort Hres1 { get { return BitConverter.ToUInt16(m_Data, 12); } set { SetUshort(12, value); } }  
  50.             /// <summary>  
  51.             /// 垂直分辨率  
  52.             /// </summary>  
  53.             public ushort Vres1 { get { return BitConverter.ToUInt16(m_Data, 14); } set { SetUshort(14, value); } }  
  54.   
  55.             public byte[] Palette  
  56.             {  
  57.                 get  
  58.                 {  
  59.                     byte[] _Palette = new byte[48];  
  60.                     Array.Copy(m_Data,16,_Palette,0,48);  
  61.                     return _Palette;  
  62.                 }  
  63.                 set  
  64.                 {  
  65.                     if(value.Length!=48)throw new Exception("错误的byte[]长度不是48");  
  66.                     Array.Copy(value, 0, m_Data, 16, 48);  
  67.                 }  
  68.   
  69.             }  
  70.             /// <summary>  
  71.             /// 位知  
  72.             /// </summary>  
  73.             public byte Reserved { get { return m_Data[64]; } set { m_Data[64] = value; } }  
  74.             /// <summary>  
  75.             /// 未知  
  76.             /// </summary>  
  77.             public byte Colour_Planes { get { return m_Data[65]; } set { m_Data[65] = value; } }  
  78.             /// <summary>  
  79.             /// 解码缓冲区  
  80.             /// </summary>  
  81.             public ushort Bytes_Per_Line { get { return BitConverter.ToUInt16(m_Data, 66); } set { SetUshort(66, value); } }  
  82.             /// <summary>  
  83.             /// 位知  
  84.             /// </summary>  
  85.             public ushort Palette_Type { get { return BitConverter.ToUInt16(m_Data, 68); } set { SetUshort(68, value); } }  
  86.             /// <summary>  
  87.             /// 填充  
  88.             /// </summary>  
  89.             public byte[] Filler  
  90.             {  
  91.                 get  
  92.                 {  
  93.                     byte[] m_Bytes = new byte[58];  
  94.                     Array.Copy(m_Data, 70, m_Bytes, 0, 58);  
  95.                     return m_Bytes;  
  96.                 }  
  97.             }  
  98.   
  99.             public PCXHEAD(byte[] p_Data)  
  100.             {  
  101.                 Array.Copy(p_Data, m_Data, 128);  
  102.             }  
  103.   
  104.             public PCXHEAD()  
  105.             {  
  106.                 m_Data[0] = 0xA;  
  107.                 Version = 0x5;  
  108.                 Encoding = 0x1;  
  109.                 Bits_Per_Pixel = 0x8;  
  110.                 Palette = new byte[] { 0x00, 0x00, 0xCD, 0x00, 0x90, 0xE7, 0x37, 0x01, 0x80, 0xF6, 0x95, 0x7C, 0x28, 0xFB, 0x95, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0xFB, 0x95, 0x7C, 0xB3, 0x16, 0x34, 0x7C, 0x00, 0x00, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x16, 0x34, 0x7C, 0x64, 0xF3, 0x37, 0x01, 0xD8, 0x54, 0xB8, 0x00 };  
  111.                 Reserved = 0x01;  
  112.                 Colour_Planes = 0x03;  
  113.                 Palette_Type = 1;  
  114.             }  
  115.   
  116.             public int Width { get { return Xmax - Xmin + 1; } }  
  117.   
  118.             public int Height { get { return Ymax - Ymin + 1; } }  
  119.   
  120.             /// <summary>  
  121.             /// 设置16位数据保存到数据表  
  122.             /// </summary>  
  123.             /// <param name="p_Index">索引</param>  
  124.             /// <param name="p_Data">数据</param>  
  125.             private void SetUshort(int p_Index, ushort p_Data)  
  126.             {  
  127.                 byte[] _ValueBytes = BitConverter.GetBytes(p_Data);  
  128.                 m_Data[p_Index] = _ValueBytes[0];  
  129.                 m_Data[p_Index + 1] = _ValueBytes[1];  
  130.             }  
  131.         }  
  132.   
  133.         private PCXHEAD m_Head = new PCXHEAD();  
  134.   
  135.         private Bitmap m_Image;  
  136.   
  137.         /// <summary>  
  138.         /// 获取图形  
  139.         /// </summary>  
  140.         public Bitmap PcxImage { get { return m_Image; } set { m_Image = value; } }  
  141.   
  142.         public ImagePcx(string p_FileFullName)  
  143.         {  
  144.             if (!File.Exists(p_FileFullName)) return;  
  145.             Load(File.ReadAllBytes(p_FileFullName));  
  146.         }  
  147.   
  148.         public ImagePcx(byte[] p_Data)  
  149.         {  
  150.             Load(p_Data);  
  151.         }  
  152.   
  153.         public ImagePcx()  
  154.         {             
  155.             
  156.         }  
  157.   
  158.         /// <summary>  
  159.         /// 开始获取数据  
  160.         /// </summary>  
  161.         /// <param name="p_Bytes">PCX文件信息</param>  
  162.         private void Load(byte[] p_Bytes)  
  163.         {  
  164.             byte[] _Bytes = p_Bytes;  
  165.             if (_Bytes[0] != 0x0A) return;              
  166.             m_Head = new PCXHEAD(_Bytes);  
  167.             m_ReadIndex = 128;  
  168.             PixelFormat _PixFormate = PixelFormat.Format24bppRgb;  
  169.             if (m_Head.Colour_Planes == 1)  
  170.             {  
  171.                 switch (m_Head.Bits_Per_Pixel)  
  172.                 {  
  173.                     case 8:  
  174.                         _PixFormate = PixelFormat.Format8bppIndexed;  
  175.                         break;  
  176.                     case 1:  
  177.                         _PixFormate = PixelFormat.Format1bppIndexed;  
  178.                         break;  
  179.                 }  
  180.             }  
  181.   
  182.             m_Image = new Bitmap(m_Head.Width, m_Head.Height, _PixFormate);  
  183.             BitmapData _Data = m_Image.LockBits(new Rectangle(0, 0, m_Image.Width, m_Image.Height), ImageLockMode.ReadWrite, _PixFormate);  
  184.             byte[] _BmpData = new byte[_Data.Stride * _Data.Height];  
  185.   
  186.             for (int i = 0; i != m_Head.Height; i++)  
  187.             {  
  188.                 byte[] _RowColorValue=http://www.mamicode.com/new byte[0];  
  189.                 switch (m_Head.Colour_Planes)  
  190.                 {  
  191.                     case 3: //24位  
  192.                         _RowColorValue = LoadPCXLine24(_Bytes);  
  193.                         break;  
  194.                     case 1: //256色  
  195.                         switch (m_Head.Bits_Per_Pixel)  
  196.                         {  
  197.                             case 8:  
  198.                                 _RowColorValue = LoadPCXLine8(_Bytes);  
  199.                                 break;  
  200.                             case 1:  
  201.                                 _RowColorValue = LoadPCXLine1(_Bytes);  
  202.                                 break;  
  203.                         }  
  204.                           
  205.                         break;  
  206.                 }             
  207.                 int _Count = _RowColorValue.Length;  
  208.                 Array.Copy(_RowColorValue, 0, _BmpData, i * _Data.Stride, _Data.Stride);  
  209.             }  
  210.             Marshal.Copy(_BmpData, 0, _Data.Scan0, _BmpData.Length);  
  211.             m_Image.UnlockBits(_Data);  
  212.   
  213.             switch (m_Head.Colour_Planes)  
  214.             {  
  215.                 case 1:  
  216.                     if (m_Head.Bits_Per_Pixel == 8)  
  217.                     {  
  218.                         ColorPalette _Palette = m_Image.Palette;  
  219.                         m_ReadIndex = p_Bytes.Length - 256 * 3;  
  220.                         for (int i = 0; i != 256; i++)  
  221.                         {  
  222.                             _Palette.Entries[i] = Color.FromArgb(p_Bytes[m_ReadIndex], p_Bytes[m_ReadIndex + 1], p_Bytes[m_ReadIndex + 2]);  
  223.                             m_ReadIndex += 3;  
  224.                         }  
  225.                         m_Image.Palette = _Palette;  
  226.                     }  
  227.                     break;  
  228.             }  
  229.         }  
  230.   
  231.         /// <summary>  
  232.         /// 保存成PCX文件  
  233.         /// </summary>  
  234.         /// <param name="p_FileFullName">完成路径</param>  
  235.         public void Save(string p_FileFullName)  
  236.         {  
  237.             if (m_Image == null) return;  
  238.             m_Head.Xmax = (ushort)(m_Image.Width - 1);  
  239.             m_Head.Ymax = (ushort)(m_Image.Height - 1);  
  240.             m_Head.Vres1 = (ushort)(m_Head.Xmax + 1);  
  241.             m_Head.Hres1 = (ushort)(m_Head.Ymax + 1);  
  242.             m_Head.Bytes_Per_Line = (ushort)m_Head.Width;  
  243.   
  244.             MemoryStream _SaveData = new MemoryStream();  
  245.   
  246.             switch (m_Image.PixelFormat)  
  247.             {  
  248.                 #region 8位  
  249.                 case PixelFormat.Format8bppIndexed:  
  250.                     m_Head.Colour_Planes = 1;  
  251.                     BitmapData _ImageData = m_Image.LockBits(new Rectangle(0, 0, m_Head.Width, m_Head.Height), ImageLockMode.ReadOnly, m_Image.PixelFormat);  
  252.                     byte[] _ImageByte = new byte[_ImageData.Stride * _ImageData.Height];  
  253.                     Marshal.Copy(_ImageData.Scan0, _ImageByte, 0, _ImageByte.Length);  
  254.                     m_Image.UnlockBits(_ImageData);  
  255.   
  256.                     m_SaveIndex = 0;  
  257.                     byte[] _RowBytes = SavePCXLine8(_ImageByte);  
  258.                     _SaveData.Write(_RowBytes, 0, _RowBytes.Length);  
  259.   
  260.                     _SaveData.WriteByte(0x0C);  
  261.                     for (int i = 0; i != 256; i++)  
  262.                     {  
  263.                         _SaveData.WriteByte((byte)m_Image.Palette.Entries[i].R);  
  264.                         _SaveData.WriteByte((byte)m_Image.Palette.Entries[i].G);  
  265.                         _SaveData.WriteByte((byte)m_Image.Palette.Entries[i].B);  
  266.                     }                      
  267.                     break;  
  268.                 #endregion  
  269.                 #region 其他都按24位保存  
  270.                 default:  
  271.                     m_Head.Colour_Planes = 3;  
  272.                     Bitmap _Bitamp24 = new Bitmap(m_Head.Width, m_Head.Height, PixelFormat.Format24bppRgb);  
  273.                     Graphics _Graphics = Graphics.FromImage(_Bitamp24);  
  274.                     _Graphics.DrawImage(m_Image, 0, 0, m_Head.Width, m_Head.Height);  
  275.                     _Graphics.Dispose();  
  276.                     BitmapData _ImageData24 = _Bitamp24.LockBits(new Rectangle(0, 0, m_Head.Width, m_Head.Height), ImageLockMode.ReadOnly, _Bitamp24.PixelFormat);  
  277.                     byte[] _ImageByte24 = new byte[_ImageData24.Stride * _ImageData24.Height];  
  278.                     Marshal.Copy(_ImageData24.Scan0, _ImageByte24, 0, _ImageByte24.Length);  
  279.                     _Bitamp24.UnlockBits(_ImageData24);  
  280.                     m_SaveIndex = 0;  
  281.                     for (int i = 0; i != _ImageData24.Height; i++)  
  282.                     {  
  283.                         m_SaveIndex = i * _ImageData24.Stride;  //2009-10-11 更新 PCX读取位置  
  284.                         byte[] _RowBytes24 = SavePCXLine24(_ImageByte24);  
  285.                         _SaveData.Write(_RowBytes24, 0, _RowBytes24.Length);  
  286.                     }  
  287.                     _SaveData.WriteByte(0x0C);  
  288.                     _SaveData.Write(new byte[768], 0, 768);  
  289.                      
  290.                     break;  
  291.                 #endregion  
  292.             }  
  293.             FileStream _FileStream = new FileStream(p_FileFullName, FileMode.Create, FileAccess.Write);  
  294.             _FileStream.Write(m_Head.m_Data, 0, 128);  
  295.             byte[] _FileData = _SaveData.ToArray();  
  296.             _FileStream.Write(_FileData, 0, _FileData.Length);  
  297.             _FileStream.Close();  
  298.         }  
  299.         
  300.         #region 取数据行  
  301.         /// <summary>  
  302.         /// 读取标记  
  303.         /// </summary>  
  304.         private int m_ReadIndex = 0;  
  305.         /// <summary>  
  306.         /// 获取PCX一行信息 24位色  
  307.         /// </summary>  
  308.         /// <param name="p_Data">数据</param>  
  309.         /// <returns>BMP的行信息</returns>  
  310.         private byte[] LoadPCXLine24(byte[] p_Data)  
  311.         {  
  312.             int _LineWidth = m_Head.Bytes_Per_Line;  
  313.             byte[] _ReturnBytes = new byte[_LineWidth * 3];  
  314.             int _EndBytesLength = p_Data.Length - 1;  
  315.             int _WriteIndex = 2;  
  316.             int _ReadIndex = 0;  
  317.             while (true)  
  318.             {  
  319.                 if (m_ReadIndex > _EndBytesLength) break; //判断行扫描结束返回码  
  320.                 byte _Data = p_Data[m_ReadIndex];  
  321.                  
  322.                 if (_Data > 0xC0)  
  323.                 {  
  324.                     int _Count = _Data - 0xC0;  
  325.                     m_ReadIndex++;  
  326.                     for (int i = 0; i != _Count; i++)  
  327.                     {  
  328.                         if (i + _ReadIndex >= _LineWidth)          //2009-6-12 RLE数据 会换行  
  329.                         {  
  330.                             _WriteIndex--;  
  331.                             _ReadIndex = 0;  
  332.                             _Count = _Count - i;  
  333.                             i = 0;  
  334.                         }  
  335.                         int _RVA = ((i + _ReadIndex) * 3) + _WriteIndex;  
  336.                         _ReturnBytes[_RVA] = p_Data[m_ReadIndex];  
  337.                     }  
  338.                     _ReadIndex += _Count;  
  339.                     m_ReadIndex++;  
  340.                 }  
  341.                 else  
  342.                 {  
  343.                     int _RVA = (_ReadIndex * 3) + _WriteIndex;  
  344.                     _ReturnBytes[_RVA] = _Data;  
  345.                     m_ReadIndex++;  
  346.                     _ReadIndex++;  
  347.                 }  
  348.                 if (_ReadIndex >= _LineWidth)  
  349.                 {  
  350.                     _WriteIndex--;  
  351.                     _ReadIndex = 0;  
  352.                 }  
  353.   
  354.                 if (_WriteIndex == -1) break;  
  355.             }  
  356.              
  357.             return _ReturnBytes;  
  358.         }  
  359.         /// <summary>  
  360.         /// 获取PCX一行信息 8位色  
  361.         /// </summary>  
  362.         /// <param name="p_Data">数据</param>  
  363.         /// <returns>BMP的行信息</returns>  
  364.         private byte[] LoadPCXLine8(byte[] p_Data)  
  365.         {  
  366.             int _LineWidth = m_Head.Bytes_Per_Line;  
  367.             byte[] _ReturnBytes = new byte[_LineWidth];  
  368.             int _EndBytesLength = p_Data.Length - 1 - (256 * 3);         //数据行不够就不执行了。。  
  369.             int _ReadIndex = 0;  
  370.             while (true)  
  371.             {  
  372.                 if (m_ReadIndex > _EndBytesLength) break; //判断行扫描结束返回码    
  373.   
  374.                 byte _Data = p_Data[m_ReadIndex];  
  375.                 if (_Data > 0xC0)  
  376.                 {  
  377.                     int _Count = _Data - 0xC0;  
  378.                     m_ReadIndex++;  
  379.                     for (int i = 0; i != _Count; i++)  
  380.                     {  
  381.                         _ReturnBytes[i + _ReadIndex] = p_Data[m_ReadIndex];  
  382.                     }  
  383.                     _ReadIndex += _Count;  
  384.                     m_ReadIndex++;  
  385.                 }  
  386.                 else  
  387.                 {  
  388.                     _ReturnBytes[_ReadIndex] = _Data;  
  389.                     m_ReadIndex++;  
  390.                     _ReadIndex++;  
  391.                 }  
  392.                 if (_ReadIndex >= _LineWidth) break;  
  393.             }  
  394.             return _ReturnBytes;  
  395.         }  
  396.         /// <summary>  
  397.         /// 获取PCX一行信息 1位色  
  398.         /// </summary>  
  399.         /// <param name="p_Data">数据</param>  
  400.         /// <returns>BMP的行信息</returns>  
  401.         private byte[] LoadPCXLine1(byte[] p_Data)  
  402.         {  
  403.             int _LineWidth = m_Head.Bytes_Per_Line;  
  404.             byte[] _ReturnBytes = new byte[_LineWidth];         
  405.             int _ReadIndex = 0;  
  406.             while (true)  
  407.             {   
  408.                 byte _Data = p_Data[m_ReadIndex];  
  409.                 if (_Data > 0xC0)  
  410.                 {  
  411.                     int _Count = _Data - 0xC0;  
  412.                     m_ReadIndex++;  
  413.                     for (int i = 0; i != _Count; i++)  
  414.                     {  
  415.                         _ReturnBytes[i + _ReadIndex] = p_Data[m_ReadIndex];  
  416.                     }  
  417.                     _ReadIndex += _Count;  
  418.                     m_ReadIndex++;  
  419.                 }  
  420.                 else  
  421.                 {  
  422.                     _ReturnBytes[_ReadIndex] = _Data;  
  423.                     m_ReadIndex++;  
  424.                     _ReadIndex++;  
  425.                 }  
  426.                 if (_ReadIndex >= _LineWidth) break;  
  427.             }  
  428.             return _ReturnBytes;  
  429.         }  
  430.         #endregion  
  431.  
  432.          
  433.         #region 存数据行  
  434.         private int m_SaveIndex = 0;  
  435.         /// <summary>  
  436.         /// 返回PCX8位色数据  
  437.         /// </summary>  
  438.         /// <param name="p_Data">原始数据</param>  
  439.         /// <returns>数据</returns>  
  440.         private byte[] SavePCXLine8(byte[] p_Data)  
  441.         {  
  442.             MemoryStream _Memory = new MemoryStream();              
  443.             byte  _Value = p_Data[m_SaveIndex];  
  444.             byte _Count = 1;  
  445.             for (int i = 1; i != p_Data.Length; i++)  
  446.             {  
  447.                 byte _Temp = p_Data[m_SaveIndex+i];  
  448.                 if (_Temp == _Value)  
  449.                 {                      
  450.                     _Count++;  
  451.                     if (_Count == 63)  
  452.                     {  
  453.                         _Memory.WriteByte(0xFF);  
  454.                         _Memory.WriteByte(_Value);  
  455.                         _Count = 0;  
  456.                     }  
  457.                 }  
  458.                 else  
  459.                 {  
  460.                     if (_Count == 1 && _Value< 0xC0 && _Value!=0x00)  
  461.                     {  
  462.                         _Memory.WriteByte(_Value);      
  463.                     }  
  464.                     else  
  465.                     {  
  466.                         _Memory.WriteByte((byte)(0xC0 + _Count));  
  467.                         _Memory.WriteByte(_Value);  
  468.                     }  
  469.                     _Count = 1;  
  470.                     _Value = _Temp;  
  471.                 }  
  472.             }  
  473.             if (_Count == 1 && _Value < 0xC0 && _Value != 0x00)  
  474.             {  
  475.                 _Memory.WriteByte(_Value);  
  476.             }  
  477.             else  
  478.             {  
  479.                 _Memory.WriteByte((byte)(0xC0 + _Count));  
  480.                 _Memory.WriteByte(_Value);  
  481.             }                         
  482.             return _Memory.ToArray();  
  483.         }  
  484.         /// <summary>  
  485.         /// 返回24位色数据  
  486.         /// </summary>  
  487.         /// <param name="p_Data">原始数据</param>  
  488.         /// <returns>数据</returns>  
  489.         private byte[] SavePCXLine24(byte[] p_Data)  
  490.         {  
  491.             MemoryStream _Read = new MemoryStream();  
  492.             MemoryStream _Green = new MemoryStream();  
  493.             MemoryStream _Blue = new MemoryStream();  
  494.   
  495.             for (int i = 0; i != m_Head.Width; i++)  
  496.             {  
  497.                 _Read.WriteByte(p_Data[m_SaveIndex+2]);  
  498.                 _Green.WriteByte(p_Data[m_SaveIndex+1]);  
  499.                 _Blue.WriteByte(p_Data[m_SaveIndex]);  
  500.                 m_SaveIndex += 3;  
  501.             }  
  502.   
  503.             MemoryStream _All = new MemoryStream();  
  504.             int _OleIndex = m_SaveIndex;  
  505.             m_SaveIndex = 0;  
  506.             byte[] _Bytes = SavePCXLine8(_Read.ToArray());  
  507.             _All.Write(_Bytes, 0, _By

    2010-5-27

    PCX RLE压缩图形的行对齐比.NET多了一位.已经修正了.

     

    2009 -7-25

    C# 转换图形为PCX 格式 增加了对1位色的PCX的读取

     

    2009-6 -12

    RLE数据压缩更改 颜色RGB在RLE压缩不换行处理.....

     

     

    .NET 支持的格式..保存成PCX格式..

    目前只支持两种结果 256色图  和24位图... 其他位的以后在说把..

     

    使用方法

     

      Zgke.MyImage.ImageFile.ImagePcx _Pcx = new Zgke.MyImage.ImageFile.ImagePcx();
                _Pcx.PcxImage = this.Icon.ToBitmap();
                _Pcx.Save(@"C:/1.pcx");

     

    如果你看这篇文章...上篇

     

     http://blog.csdn.net/zgke/archive/2009/05/19/4201621.aspx C#解析PCX图形文件

    可以忽略了.下面的代码包含读和保存的功能..目前能保存256色图 和24位图..如果你的图形不是这两种 ..代码里把你的图形复制成24位的图 .然后去保存..

     

    全部代码.

  508. using System;using System.Collections.Generic;using System.Text;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Runtime.InteropServices;namespace Zgke.MyImage.ImageFile{    /// <summary>    /// PCX操作类    /// zgke@sina.com    /// qq:116149    /// </summary>    public class ImagePcx    {        /// <summary>        /// PCX文件头        /// </summary>        private class PCXHEAD        {            public byte[] m_Data = http://www.mamicode.com/new byte[128];"错误的byte[]长度不是48");                    Array.Copy(value, 0, m_Data, 16, 48);                }            }            /// <summary>            /// 位知            /// </summary>            public byte Reserved { get { return m_Data[64]; } set { m_Data[64] = value; } }            /// <summary>            /// 未知            /// </summary>            public byte Colour_Planes { get { return m_Data[65]; } set { m_Data[65] = value; } }            /// <summary>            /// 解码缓冲区            /// </summary>            public ushort Bytes_Per_Line { get { return BitConverter.ToUInt16(m_Data, 66); } set { SetUshort(66, value); } }            /// <summary>            /// 位知            /// </summary>            public ushort Palette_Type { get { return BitConverter.ToUInt16(m_Data, 68); } set { SetUshort(68, value); } }            /// <summary>            /// 填充            /// </summary>            public byte[] Filler            {                get                {                    byte[] m_Bytes = new byte[58];                    Array.Copy(m_Data, 70, m_Bytes, 0, 58);                    return m_Bytes;                }            }            public PCXHEAD(byte[] p_Data)            {                Array.Copy(p_Data, m_Data, 128);            }            public PCXHEAD()            {                m_Data[0] = 0xA;                Version = 0x5;                Encoding = 0x1;                Bits_Per_Pixel = 0x8;                Palette = new byte[] { 0x00, 0x00, 0xCD, 0x00, 0x90, 0xE7, 0x37, 0x01, 0x80, 0xF6, 0x95, 0x7C, 0x28, 0xFB, 0x95, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0xFB, 0x95, 0x7C, 0xB3, 0x16, 0x34, 0x7C, 0x00, 0x00, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x16, 0x34, 0x7C, 0x64, 0xF3, 0x37, 0x01, 0xD8, 0x54, 0xB8, 0x00 };                Reserved = 0x01;                Colour_Planes = 0x03;                Palette_Type = 1;            }            public int Width { get { return Xmax - Xmin + 1; } }            public int Height { get { return Ymax - Ymin + 1; } }            /// <summary>            /// 设置16位数据保存到数据表            /// </summary>            /// <param name="p_Index">索引</param>            /// <param name="p_Data">数据</param>            private void SetUshort(int p_Index, ushort p_Data)            {                byte[] _ValueBytes = BitConverter.GetBytes(p_Data);                m_Data[p_Index] = _ValueBytes[0];                m_Data[p_Index + 1] = _ValueBytes[1];            }        }        private PCXHEAD m_Head = new PCXHEAD();        private Bitmap m_Image;        /// <summary>        /// 获取图形        /// </summary>        public Bitmap PcxImage { get { return m_Image; } set { m_Image = value; } }        public ImagePcx(string p_FileFullName)        {            if (!File.Exists(p_FileFullName)) return;            Load(File.ReadAllBytes(p_FileFullName));        }        public ImagePcx(byte[] p_Data)        {            Load(p_Data);        }        public ImagePcx()        {                             }        /// <summary>        /// 开始获取数据        /// </summary>        /// <param name="p_Bytes">PCX文件信息</param>        private void Load(byte[] p_Bytes)        {            byte[] _Bytes = p_Bytes;            if (_Bytes[0] != 0x0A) return;                        m_Head = new PCXHEAD(_Bytes);            m_ReadIndex = 128;            PixelFormat _PixFormate = PixelFormat.Format24bppRgb;            if (m_Head.Colour_Planes == 1)            {                switch (m_Head.Bits_Per_Pixel)                {                    case 8:                        _PixFormate = PixelFormat.Format8bppIndexed;                        break;                    case 1:                        _PixFormate = PixelFormat.Format1bppIndexed;                        break;                }            }            m_Image = new Bitmap(m_Head.Width, m_Head.Height, _PixFormate);            BitmapData _Data = http://www.mamicode.com/m_Image.LockBits(new Rectangle(0, 0, m_Image.Width, m_Image.Height), ImageLockMode.ReadWrite, _PixFormate);"p_FileFullName">完成路径</param>        public void Save(string p_FileFullName)        {            if (m_Image == null) return;            m_Head.Xmax = (ushort)(m_Image.Width - 1);            m_Head.Ymax = (ushort)(m_Image.Height - 1);            m_Head.Vres1 = (ushort)(m_Head.Xmax + 1);            m_Head.Hres1 = (ushort)(m_Head.Ymax + 1);            m_Head.Bytes_Per_Line = (ushort)m_Head.Width;            MemoryStream _SaveData = http://www.mamicode.com/new MemoryStream();"p_Data">数据</param>        /// <returns>BMP的行信息</returns>        private byte[] LoadPCXLine24(byte[] p_Data)        {            int _LineWidth = m_Head.Bytes_Per_Line;            byte[] _ReturnBytes = new byte[_LineWidth * 3];            int _EndBytesLength = p_Data.Length - 1;            int _WriteIndex = 2;            int _ReadIndex = 0;            while (true)            {                if (m_ReadIndex > _EndBytesLength) break; //判断行扫描结束返回码                byte _Data = http://www.mamicode.com/p_Data[m_ReadIndex];"p_Data">数据</param>        /// <returns>BMP的行信息</returns>        private byte[] LoadPCXLine8(byte[] p_Data)        {            int _LineWidth = m_Head.Bytes_Per_Line;            byte[] _ReturnBytes = new byte[_LineWidth];            int _EndBytesLength = p_Data.Length - 1 - (256 * 3);         //数据行不够就不执行了。。            int _ReadIndex = 0;            while (true)            {                if (m_ReadIndex > _EndBytesLength) break; //判断行扫描结束返回码                  byte _Data = http://www.mamicode.com/p_Data[m_ReadIndex];"p_Data">数据</param>        /// <returns>BMP的行信息</returns>        private byte[] LoadPCXLine1(byte[] p_Data)        {            int _LineWidth = m_Head.Bytes_Per_Line;            byte[] _ReturnBytes = new byte[_LineWidth];                   int _ReadIndex = 0;            while (true)            {                 byte _Data = http://www.mamicode.com/p_Data[m_ReadIndex];"p_Data">原始数据</param>        /// <returns>数据</returns>        private byte[] SavePCXLine8(byte[] p_Data)        {            MemoryStream _Memory = new MemoryStream();                        byte  _Value = http://www.mamicode.com/p_Data[m_SaveIndex];"p_Data">原始数据</param>        /// <returns>数据</returns>        private byte[] SavePCXLine24(byte[] p_Data)        {            MemoryStream _Read = new MemoryStream();            MemoryStream _Green = new MemoryStream();            MemoryStream _Blue = new MemoryStream();            for (int i = 0; i != m_Head.Width; i++)            {                _Read.WriteByte(p_Data[m_SaveIndex+2]);                _Green.WriteByte(p_Data[m_SaveIndex+1]);                _Blue.WriteByte(p_Data[m_SaveIndex]);                m_SaveIndex += 3;            }            MemoryStream _All = new MemoryStream();            int _OleIndex = m_SaveIndex;            m_SaveIndex = 0;            byte[] _Bytes = SavePCXLine8(_Read.ToArray());            _All.Write(_Bytes, 0, _Bytes.Length);            m_SaveIndex = 0;            _Bytes = SavePCXLine8(_Green.ToArray());            _All.Write(_Bytes, 0, _Bytes.Length);            m_SaveIndex = 0;            _Bytes = SavePCXLine8(_Blue.ToArray());            _All.Write(_Bytes, 0, _Bytes.Length);            m_SaveIndex = _OleIndex;            return _All.ToArray();        }        #endregion    }}

     转自:http://blog.csdn.net/zgke/article/details/4204090

C# 转换图形为PCX 格式