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位的图 .然后去保存..

全部代码...

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

    全部代码.

  471. 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 = new byte[128]; /// <summary>
    /// 文件头必须为 0A;
    /// </summary>
    public byte Manufacturer { get { return m_Data[0]; } }
    /// <summary>
    /// 0:PC Paintbrush 2.5 版   2:PC Paintbrush 2.8 版  5:PC Paintbrush 3.0 版
    /// </summary>
    public byte Version { get { return m_Data[1]; } set { m_Data[1] = value; } }
    /// <summary>
    /// 其值为1时表示采用RLE压缩编码的方法
    /// </summary>
    public byte Encoding { get { return m_Data[2]; } set { m_Data[2] = value; } }
    /// <summary>
    /// 每个相素的位数
    /// </summary>
    public byte Bits_Per_Pixel { get { return m_Data[3]; } set { m_Data[3] = value; } } public ushort Xmin { get { return BitConverter.ToUInt16(m_Data, 4); } set { SetUshort(4, value); } }
    public ushort Ymin { get { return BitConverter.ToUInt16(m_Data, 6); } set { SetUshort(6, value); } }
    public ushort Xmax { get { return BitConverter.ToUInt16(m_Data, 8); } set { SetUshort(8, value); } }
    public ushort Ymax { get { return BitConverter.ToUInt16(m_Data, 10); } set { SetUshort(10, value); } }
    /// <summary>
    /// 水平分辨率
    /// </summary>
    public ushort Hres1 { get { return BitConverter.ToUInt16(m_Data, 12); } set { SetUshort(12, value); } }
    /// <summary>
    /// 垂直分辨率
    /// </summary>
    public ushort Vres1 { get { return BitConverter.ToUInt16(m_Data, 14); } set { SetUshort(14, value); } } public byte[] Palette
    {
    get
    {
    byte[] _Palette = new byte[48];
    Array.Copy(m_Data,16,_Palette,0,48);
    return _Palette;
    }
    set
    {
    if(value.Length!=48)throw new Exception("错误的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 = m_Image.LockBits(new Rectangle(0, 0, m_Image.Width, m_Image.Height), ImageLockMode.ReadWrite, _PixFormate);
    byte[] _BmpData = new byte[_Data.Stride * _Data.Height]; for (int i = 0; i != m_Head.Height; i++)
    {
    byte[] _RowColorValue=new byte[0];
    switch (m_Head.Colour_Planes)
    {
    case 3: //24位
    _RowColorValue = LoadPCXLine24(_Bytes);
    break;
    case 1: //256色
    switch (m_Head.Bits_Per_Pixel)
    {
    case 8:
    _RowColorValue = LoadPCXLine8(_Bytes);
    break;
    case 1:
    _RowColorValue = LoadPCXLine1(_Bytes);
    break;
    } break;
    }
    int _Count = _RowColorValue.Length;
    Array.Copy(_RowColorValue, 0, _BmpData, i * _Data.Stride, _Data.Stride);
    }
    Marshal.Copy(_BmpData, 0, _Data.Scan0, _BmpData.Length);
    m_Image.UnlockBits(_Data); switch (m_Head.Colour_Planes)
    {
    case 1:
    if (m_Head.Bits_Per_Pixel == 8)
    {
    ColorPalette _Palette = m_Image.Palette;
    m_ReadIndex = p_Bytes.Length - 256 * 3;
    for (int i = 0; i != 256; i++)
    {
    _Palette.Entries[i] = Color.FromArgb(p_Bytes[m_ReadIndex], p_Bytes[m_ReadIndex + 1], p_Bytes[m_ReadIndex + 2]);
    m_ReadIndex += 3;
    }
    m_Image.Palette = _Palette;
    }
    break;
    }
    } /// <summary>
    /// 保存成PCX文件
    /// </summary>
    /// <param name="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 = new MemoryStream(); switch (m_Image.PixelFormat)
    {
    #region 8位
    case PixelFormat.Format8bppIndexed:
    m_Head.Colour_Planes = 1;
    BitmapData _ImageData = m_Image.LockBits(new Rectangle(0, 0, m_Head.Width, m_Head.Height), ImageLockMode.ReadOnly, m_Image.PixelFormat);
    byte[] _ImageByte = new byte[_ImageData.Stride * _ImageData.Height];
    Marshal.Copy(_ImageData.Scan0, _ImageByte, 0, _ImageByte.Length);
    m_Image.UnlockBits(_ImageData); m_SaveIndex = 0;
    byte[] _RowBytes = SavePCXLine8(_ImageByte);
    _SaveData.Write(_RowBytes, 0, _RowBytes.Length); _SaveData.WriteByte(0x0C);
    for (int i = 0; i != 256; i++)
    {
    _SaveData.WriteByte((byte)m_Image.Palette.Entries[i].R);
    _SaveData.WriteByte((byte)m_Image.Palette.Entries[i].G);
    _SaveData.WriteByte((byte)m_Image.Palette.Entries[i].B);
    }
    break;
    #endregion
    #region 其他都按24位保存
    default:
    m_Head.Colour_Planes = 3;
    Bitmap _Bitamp24 = new Bitmap(m_Head.Width, m_Head.Height, PixelFormat.Format24bppRgb);
    Graphics _Graphics = Graphics.FromImage(_Bitamp24);
    _Graphics.DrawImage(m_Image, 0, 0, m_Head.Width, m_Head.Height);
    _Graphics.Dispose();
    BitmapData _ImageData24 = _Bitamp24.LockBits(new Rectangle(0, 0, m_Head.Width, m_Head.Height), ImageLockMode.ReadOnly, _Bitamp24.PixelFormat);
    byte[] _ImageByte24 = new byte[_ImageData24.Stride * _ImageData24.Height];
    Marshal.Copy(_ImageData24.Scan0, _ImageByte24, 0, _ImageByte24.Length);
    _Bitamp24.UnlockBits(_ImageData24);
    m_SaveIndex = 0;
    for (int i = 0; i != _ImageData24.Height; i++)
    {
    m_SaveIndex = i * _ImageData24.Stride; //2009-10-11 更新 PCX读取位置
    byte[] _RowBytes24 = SavePCXLine24(_ImageByte24);
    _SaveData.Write(_RowBytes24, 0, _RowBytes24.Length);
    }
    _SaveData.WriteByte(0x0C);
    _SaveData.Write(new byte[768], 0, 768); break;
    #endregion
    }
    FileStream _FileStream = new FileStream(p_FileFullName, FileMode.Create, FileAccess.Write);
    _FileStream.Write(m_Head.m_Data, 0, 128);
    byte[] _FileData = _SaveData.ToArray();
    _FileStream.Write(_FileData, 0, _FileData.Length);
    _FileStream.Close();
    } #region 取数据行
    /// <summary>
    /// 读取标记
    /// </summary>
    private int m_ReadIndex = 0;
    /// <summary>
    /// 获取PCX一行信息 24位色
    /// </summary>
    /// <param name="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 = p_Data[m_ReadIndex]; if (_Data > 0xC0)
    {
    int _Count = _Data - 0xC0;
    m_ReadIndex++;
    for (int i = 0; i != _Count; i++)
    {
    if (i + _ReadIndex >= _LineWidth) //2009-6-12 RLE数据 会换行
    {
    _WriteIndex--;
    _ReadIndex = 0;
    _Count = _Count - i;
    i = 0;
    }
    int _RVA = ((i + _ReadIndex) * 3) + _WriteIndex;
    _ReturnBytes[_RVA] = p_Data[m_ReadIndex];
    }
    _ReadIndex += _Count;
    m_ReadIndex++;
    }
    else
    {
    int _RVA = (_ReadIndex * 3) + _WriteIndex;
    _ReturnBytes[_RVA] = _Data;
    m_ReadIndex++;
    _ReadIndex++;
    }
    if (_ReadIndex >= _LineWidth)
    {
    _WriteIndex--;
    _ReadIndex = 0;
    } if (_WriteIndex == -1) break;
    } return _ReturnBytes;
    }
    /// <summary>
    /// 获取PCX一行信息 8位色
    /// </summary>
    /// <param name="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 = p_Data[m_ReadIndex];
    if (_Data > 0xC0)
    {
    int _Count = _Data - 0xC0;
    m_ReadIndex++;
    for (int i = 0; i != _Count; i++)
    {
    _ReturnBytes[i + _ReadIndex] = p_Data[m_ReadIndex];
    }
    _ReadIndex += _Count;
    m_ReadIndex++;
    }
    else
    {
    _ReturnBytes[_ReadIndex] = _Data;
    m_ReadIndex++;
    _ReadIndex++;
    }
    if (_ReadIndex >= _LineWidth) break;
    }
    return _ReturnBytes;
    }
    /// <summary>
    /// 获取PCX一行信息 1位色
    /// </summary>
    /// <param name="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 = p_Data[m_ReadIndex];
    if (_Data > 0xC0)
    {
    int _Count = _Data - 0xC0;
    m_ReadIndex++;
    for (int i = 0; i != _Count; i++)
    {
    _ReturnBytes[i + _ReadIndex] = p_Data[m_ReadIndex];
    }
    _ReadIndex += _Count;
    m_ReadIndex++;
    }
    else
    {
    _ReturnBytes[_ReadIndex] = _Data;
    m_ReadIndex++;
    _ReadIndex++;
    }
    if (_ReadIndex >= _LineWidth) break;
    }
    return _ReturnBytes;
    }
    #endregion #region 存数据行
    private int m_SaveIndex = 0;
    /// <summary>
    /// 返回PCX8位色数据
    /// </summary>
    /// <param name="p_Data">原始数据</param>
    /// <returns>数据</returns>
    private byte[] SavePCXLine8(byte[] p_Data)
    {
    MemoryStream _Memory = new MemoryStream();
    byte _Value = p_Data[m_SaveIndex];
    byte _Count = 1;
    for (int i = 1; i != p_Data.Length; i++)
    {
    byte _Temp = p_Data[m_SaveIndex+i];
    if (_Temp == _Value)
    {
    _Count++;
    if (_Count == 63)
    {
    _Memory.WriteByte(0xFF);
    _Memory.WriteByte(_Value);
    _Count = 0;
    }
    }
    else
    {
    if (_Count == 1 && _Value< 0xC0 && _Value!=0x00)
    {
    _Memory.WriteByte(_Value);
    }
    else
    {
    _Memory.WriteByte((byte)(0xC0 + _Count));
    _Memory.WriteByte(_Value);
    }
    _Count = 1;
    _Value = _Temp;
    }
    }
    if (_Count == 1 && _Value < 0xC0 && _Value != 0x00)
    {
    _Memory.WriteByte(_Value);
    }
    else
    {
    _Memory.WriteByte((byte)(0xC0 + _Count));
    _Memory.WriteByte(_Value);
    }
    return _Memory.ToArray();
    }
    /// <summary>
    /// 返回24位色数据
    /// </summary>
    /// <param name="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 格式的更多相关文章

  1. 关于Web项目里的给表单验证控件添加结束时间不得小于开始时间的验证方法,日期转换和前台显示格式之间,还有JSON取日期数据格式转换成标准日期格式的问题

    项目里有些不同页面间的日期显示格式是不同的, 第一个问题: 比如我用日期控件WdatePicker.js导包后只需在input标签里加上onClick="WdatePicker()" ...

  2. Java将其他数据格式转换成json字符串格式

    package com.wangbo.util; import java.beans.IntrospectionException; import java.beans.Introspector; i ...

  3. 【好文翻译】一步一步教你使用Spire.Doc转换Word文档格式

    背景: 年11月,微软宣布作为ECMA国际主要合作伙伴,将其开发的基于XML的文件格式标准化,称之为"Office Open XML" .Open XML的引进使office文档结 ...

  4. Ultra UltraEdit中取消提示:你要转换 File 为 DOS 格式吗?

    Ultra Edit中取消提示:文件可能不是DOS格式,你要转换 File 为 DOS 格式吗? UE 提示 取消取消这个提示: 高级 -> 配置 -> 文件处理 -> DOS/UN ...

  5. Oracle 如何将“26-9月 -17 06.46.00.000000000 下午”字符串转换成标准日期格式

    今天,在读取日期格式数据时,出现这样的格式“26-9月 -17 06.46.00.000000000 下午”,在网上找了一下, 这个也是oracle的一种日期保存格式,数据都是日期类型,只是显示的结果 ...

  6. angular学习笔记(二十五)-$http(3)-转换请求和响应格式

    本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ...

  7. RSA的密钥把JAVA格式转换成C#的格式(2)

    把C#格式转换成Java:RSA的密钥把JAVA格式转换成C#的格式(1) 我已经在第一篇介绍过如何把C#格式转换成Java,现在来看看如何把Java格式转换成C#. /// <summary& ...

  8. UTCformat 转换UTC时间并格式化成本地时间

    /** * UTCformat 转换UTC时间并格式化成本地时间 * @param {string} utc */ UTCformat (utc) { var date = new Date(utc) ...

  9. Linux: 给右键菜单加一个“转换图片为jpg格式”

    Linux上通常都会安装imagemagick这个小巧但又异常强大的工具.这个软件提供了一系列很好用的功能.这里说一说如何使用它的convert命令转换图片为jpg格式,以及如何把它添加到Thunar ...

随机推荐

  1. redis tutorail

    命令 set     get    incr expire  秒  ttl    -1 不会过期 list  : lpush  rpush  lpop  rpop   lrange   llen se ...

  2. MyBatis3.4.0以上的分页插件错误:Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.stateme

    错误: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named p ...

  3. 移动端,PC端,微信等常用平台和浏览器判断

    var wzw={ //浏览器相关信息 //android webview 需要app进行支持,Android web view初始化时,在navigator中添加标识 browser:{ versi ...

  4. HDU 3374 String Problem(KMP+最大(最小)表示)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:给出一个字符串,依次左移一个单位形成一堆字符串,求其字典序最小和最大的字符串需要左移多 ...

  5. Elasticsearch的相关知识

    Elasticsearch的备份和恢复 http://keenwon.com/1393.html ETL kettle 数据转成json 发送POST请求 http://blog.csdn.net/a ...

  6. day5模块学习--configparser模块

       使用ConfigParser模块读写ini文件(http://blog.csdn.net/linda1000/article/details/11729561) ConfigParserPyth ...

  7. javascript大神修炼记(6)——OOP思想(继承)

    读者朋友们大家好,我们今天这一讲就接着前面的封装继续讲解,今天就是在前面内容上面的升级,OOP思想中的继承,我们就先来解释一下继承到底是什么意思,我们在什么地方会用到继续. 继承就是,后代继续祖先的一 ...

  8. Git github webhook 自动更新/部署代码 php自动更新脚本

    这几天尝试了利用github的webhook,当代码更新到github,我们的测试服务器自动更新最新的gitbub仓库代码. 先列几个大概步骤,有时间再补充详细 1 . 服务器生成ssh key,一般 ...

  9. 黑马程序员_java基础笔记(02)...java语言基础组成

    ——————————  ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— java语法(1:关键字,2:标识符,3:注释,4:常量和变量,5:运算符,6:语 ...

  10. 深度学习基础系列(十一)| Keras中图像增强技术详解

    在深度学习中,数据短缺是我们经常面临的一个问题,虽然现在有不少公开数据集,但跟大公司掌握的海量数据集相比,数量上仍然偏少,而某些特定领域的数据采集更是非常困难.根据之前的学习可知,数据量少带来的最直接 ...