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. namespace Zgke.MyImage.ImageFile
  9. {
  10. /// <summary>
  11. /// PCX操作类
  12. /// [email protected]
  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操作类
        /// [email protected]
        /// 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

时间: 2024-11-09 00:45:09

C# 转换图形为PCX 格式的相关文章

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

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

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

背景: 本文试图证明和审查Spire.Doc的格式转换能力.很长的一段时间里,为了操作文档,开发人员不得不在服务器上安装Office软件.首先,这是一个很糟糕的设计和实践.第二,微软从没打算把Office作为一个服务器组件,它也用来在服务器端解释和操作文档的.于是乎,产生了类似Spire.Doc这样的类库.当我们讨论这个问题时,值得一提的是 Office Open Xml. Office Open XML (也有非正式地称呼为 OOXML 或OpenXML) 是一种压缩的, 基于XML的文件格式

java将其他数据格式转换成json字符串格式

package com.wangbo.util; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; import java.util.List; import

分钟数转换成倒计时,格式 _天_时_分

#region 分钟数转换成倒计时,格式 _天_时_分 + string MinutesToCountdown(int Minutes) /// <summary> /// 将分钟数转换成倒计时 格式:_天_时_分 /// </summary> /// <param name="Minutes">分钟数</param> /// <returns></returns> public static string Min

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

项目里有些不同页面间的日期显示格式是不同的, 第一个问题: 比如我用日期控件WdatePicker.js导包后只需在input标签里加上onClick="WdatePicker()"就可以用了,但是默认是没有时分秒的,如果需要显示时分秒只需要加上WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})就行. **************************************************************************

PDF怎么转换成html网页格式

PDF作为一种通用的文件格式,被广泛的应用在生活.工作中.可是有时候需要将它转换成其他格式的,PDF怎么转换成html格式的?目前有一款PDF转换成html的转换器非常受网友的喜欢,那就是迅捷PDF转换器,这款转换器功能非常强大,支持多种文件格式之间的相互转换.下面看看如何利用这个转换器将PDF转换成网页格式的. 首先大家应该将这款转换工具下载安装到自己的电脑上,只要一款pdf转换成html转换器就能解决各种文件转换的问题. 步骤一:打开迅捷PDF转换器,大家可以看到十种转换模式,这里我们选择“

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

本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transformRequest: function(data){ //对前台发送的data进行处理 return data } }) 这个在测试的时候遇到了很大的问题.只要经过transformRequest函数处理,哪怕是不做任何处理,node后台都会报错,需要尝试使用php 2. transformResp

CAD编辑中可以把CAD图纸转换成JPG图片格式吗?

CAD编辑中可以把CAD图纸转换成jpg格式的图片吗?一般小伙伴们可能知道的是在CAD编辑器中绘制CAD图纸,如果需要转换CAD图纸格式的话,一般都是借助CAD转换器来进行转换的,那么如何在CAD编辑器中转换图纸格式呢?CAD编辑器中可以把CAD图纸转换成JPG图纸格式吗?具体要怎么来进行操作?那下面小编就来教教大家具体操作方法,小伙伴们可以学习一下. 第一步:首先,打开电脑,在电脑桌面上任意的打开一个浏览器,在浏览器的搜索框中搜索迅捷CAD编辑器(标准版),然后在搜索的结果中,点击官网进行,根

怎么将一张CAD图纸文件转换成一张图片的格式呢?

怎么将一张CAD图纸文件转换成一张图片的格式呢?CAD格式的图纸文件都可以将其转换成dwg或是其他一些格式的,有时候在我们拿到打开一张CAD图纸的时候需要将其转换成图片格式时候,我们应该如何进行操作呢?今天小编就要来教教大家怎么将一张CAD图纸文件转换成一张图片格式的全部操作步骤了,希望大家进行采纳! 第一步:首先打开电脑上面的CAD转换器,如果您们电脑上面没有CAD转换器这款软件的话,你们就可以去到软件商店或是官网上面直接去进行下载!就可以和小编使用一样的CAD转换器软件了!第二步:进入到转换