C# CUR类实现代码
C# CUR类实现代码
发布时间:2016-12-29 来源:查字典编辑
摘要:复制代码代码如下:usingSystem;usingSystem.Collections.Generic;usingSystem.Colle...

复制代码 代码如下:

using System;

using System.Collections.Generic;

using System.Collections;

using System.Text;

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Runtime.InteropServices;

namespace Zgke.MyImage.ImageFile

{

/// <summary>

/// CUR文件操作类

/// zgke@sina.com

/// qq:116149

/// </summary>

public class ImageCur

{

private class CurHead

{

private byte[] m_Retain = new byte[2];

private byte[] m_Type = new byte[] { 0x02, 0x00 };

private byte[] m_ImageCount = new byte[2];

private byte m_ImageWidth;

private byte m_ImageHeight;

private byte m_ColorCount;

private byte[] m_NotUser = new byte[5];

private byte[] m_ImageLength = new byte[4];

private byte[] m_ImageRVA = new byte[4];

/// <summary>

/// 图形高

/// </summary>

public byte ImageHeight { get { return m_ImageHeight; } set { m_ImageHeight = value; } }

/// <summary>

/// 图象个数

/// </summary>

public ushort ImageCount { get { return BitConverter.ToUInt16(m_ImageCount, 0); } set { m_ImageCount = BitConverter.GetBytes(value); } }

/// <summary>

/// 图形宽

/// </summary>

public byte ImageWidth { get { return m_ImageWidth; } set { m_ImageWidth = value; } }

/// <summary>

/// 色彩数 (256以下色用)

/// </summary>

public byte ColorCount { get { return m_ColorCount; } set { m_ColorCount = value; } }

/// <summary>

/// 图象数据块的长度

/// </summary>

public uint ImageLength { get { return BitConverter.ToUInt32(m_ImageLength, 0); } set { m_ImageLength = BitConverter.GetBytes(value); } }

/// <summary>

/// 图象数据块相对于文件头部的偏移量

/// </summary>

public uint ImageRVA { get { return BitConverter.ToUInt32(m_ImageRVA, 0); } set { m_ImageRVA = BitConverter.GetBytes(value); } }

public CurHead()

{

}

public CurHead(byte[] p_Data)

{

ImageCount = BitConverter.ToUInt16(p_Data, 4);

ImageHeight = p_Data[7];

ImageWidth = p_Data[6];

ColorCount = p_Data[8];

ImageLength = BitConverter.ToUInt32(p_Data, 14);

ImageRVA = BitConverter.ToUInt32(p_Data, 18);

}

public byte[] GetByte()

{

byte[] _ReturnBytes = new byte[22];

_ReturnBytes[0] = m_Retain[0];

_ReturnBytes[1] = m_Retain[1];

_ReturnBytes[2] = m_Retain[0];

_ReturnBytes[3] = m_Retain[1];

_ReturnBytes[4] = m_ImageCount[0];

_ReturnBytes[5] = m_ImageCount[1];

_ReturnBytes[6] = m_ImageWidth;

_ReturnBytes[7] = m_ImageHeight;

_ReturnBytes[8] = m_ColorCount;

_ReturnBytes[14] = m_ImageLength[0];

_ReturnBytes[15] = m_ImageLength[1];

_ReturnBytes[16] = m_ImageLength[2];

_ReturnBytes[17] = m_ImageLength[3];

_ReturnBytes[18] = m_ImageRVA[0];

_ReturnBytes[19] = m_ImageRVA[1];

_ReturnBytes[20] = m_ImageRVA[2];

_ReturnBytes[21] = m_ImageRVA[3];

return _ReturnBytes;

}

public byte[] GetImageByte()

{

byte[] _ReturnBytes = new byte[16];

_ReturnBytes[0] = m_ImageWidth;

_ReturnBytes[1] = m_ImageHeight;

_ReturnBytes[2] = m_ColorCount;

_ReturnBytes[8] = m_ImageLength[0];

_ReturnBytes[9] = m_ImageLength[1];

_ReturnBytes[10] = m_ImageLength[2];

_ReturnBytes[11] = m_ImageLength[3];

_ReturnBytes[12] = m_ImageRVA[0];

_ReturnBytes[13] = m_ImageRVA[1];

_ReturnBytes[14] = m_ImageRVA[2];

_ReturnBytes[15] = m_ImageRVA[3];

return _ReturnBytes;

}

}

private CurHead m_CurHead;

private Bitmap m_CurImage;

private IList<Image> m_CurList =new List<Image>();

public ImageCur(string p_FileFullName)

{

byte[] _FileBytes = File.ReadAllBytes(p_FileFullName);

ImageCurBytes(_FileBytes);

}

public ImageCur(byte[] p_FileBytes)

{

ImageCurBytes(p_FileBytes);

}

private void ImageCurBytes(byte[] p_Bytes)

{

m_CurHead = new CurHead(p_Bytes);

for (int i = 0; i != m_CurHead.ImageCount; i++)

{

m_CurHead.ImageWidth = (byte)BitConverter.ToInt16(p_Bytes, (int)m_CurHead.ImageRVA + 4);

m_CurHead.ImageHeight = (byte)(BitConverter.ToInt16(p_Bytes, (int)m_CurHead.ImageRVA + 8) / 2);

short _Piex = BitConverter.ToInt16(p_Bytes, (int)m_CurHead.ImageRVA + 14);

LoadImgae(_Piex, p_Bytes, (int)m_CurHead.ImageRVA + 40);

m_CurList.Add((Image)m_CurImage);

byte[] _Value = new byte[4];

_Value[3] = p_Bytes[((i + 1) * 16) + 18 + 3];

_Value[2] = p_Bytes[((i + 1) * 16) + 18 + 2];

_Value[1] = p_Bytes[((i + 1) * 16) + 18 + 1];

_Value[0] = p_Bytes[((i + 1) * 16) + 18];

m_CurHead.ImageRVA = BitConverter.ToUInt32(_Value, 0);

}

}

public ImageCur()

{

}

#region Read

private void Load32(byte[] p_FileBytes, byte[] p_NewData, int p_ReadIndex, int p_Width, int p_Height, int p_MashIndex, BitmapData p_NewBitmapData)

{

int _WriteIndex = 0;

for (int i = p_NewBitmapData.Height - 1; i != -1; i--)

{

_WriteIndex = i * p_NewBitmapData.Stride;

for (int z = 0; z != p_NewBitmapData.Width; z++)

{

p_NewData[_WriteIndex + (z * 4)] = p_FileBytes[p_ReadIndex];

p_NewData[_WriteIndex + (z * 4) + 1] = p_FileBytes[p_ReadIndex + 1];

p_NewData[_WriteIndex + (z * 4) + 2] = p_FileBytes[p_ReadIndex + 2];

p_NewData[_WriteIndex + (z * 4) + 3] = p_FileBytes[p_ReadIndex + 3];

p_ReadIndex += 4;

}

}

}

private void Load24(byte[] p_FileBytes, byte[] p_NewData, int p_ReadIndex, int p_Width, int p_Height, int p_MashIndex, BitmapData p_NewBitmapData)

{

int _WriteIndex = 0;

int _MashStride = p_Width / 8;

if (p_Width % 8 != 0) _MashStride++;

if (_MashStride % 4 != 0) _MashStride += _MashStride % 4;

byte[] _MashBytes = new byte[_MashStride * p_Height];

Array.Copy(p_FileBytes, p_MashIndex, _MashBytes, 0, _MashBytes.Length);

for (int i = 0; i != _MashBytes.Length; i++)

{

_MashBytes[i] = ConvertByte.OperateData.ReverseByte(_MashBytes[i]);

}

BitArray _MashArray = new BitArray(_MashBytes);

for (int i = p_NewBitmapData.Height - 1; i != -1; i--)

{

p_MashIndex = (p_Height - 1 - i) * (_MashStride * 8);

_WriteIndex = i * p_NewBitmapData.Stride;

for (int z = 0; z != p_NewBitmapData.Width; z++)

{

p_NewData[_WriteIndex + (z * 4)] = p_FileBytes[p_ReadIndex];

p_NewData[_WriteIndex + (z * 4) + 1] = p_FileBytes[p_ReadIndex + 1];

p_NewData[_WriteIndex + (z * 4) + 2] = p_FileBytes[p_ReadIndex + 2];

p_NewData[_WriteIndex + (z * 4) + 3] = 0xFF;

if (_MashArray[p_MashIndex])p_NewData[_WriteIndex + (z * 4) + 3] = 0x00; //

p_ReadIndex += 3;

p_MashIndex++;

}

}

}

private void Load8(byte[] p_FileBytes, byte[] p_NewData, int p_ReadIndex, int p_Width, int p_Height, int p_MashIndex, BitmapData p_NewBitmapData)

{

int _WriteIndex = 0;

Hashtable _ColorHashTable = new Hashtable();

for (int i = 0; i != 256; i++)

{

_ColorHashTable.Add(i.ToString(), Color.FromArgb(p_FileBytes[p_ReadIndex + 3], p_FileBytes[p_ReadIndex + 2], p_FileBytes[p_ReadIndex + 1], p_FileBytes[p_ReadIndex]));

p_ReadIndex += 4;

}

p_MashIndex = p_Width * p_Height + p_ReadIndex;

int _MashStride = p_Width / 8;

if (p_Width % 8 != 0) _MashStride++;

if (_MashStride % 4 !=0) _MashStride += _MashStride % 4;

byte[] _MashBytes = new byte[_MashStride * p_Height];

Array.Copy(p_FileBytes, p_MashIndex, _MashBytes, 0, _MashBytes.Length);

for (int i = 0; i != _MashBytes.Length; i++)

{

_MashBytes[i] = ConvertByte.OperateData.ReverseByte(_MashBytes[i]);

}

BitArray _MashArray = new BitArray(_MashBytes);

for (int i = p_NewBitmapData.Height - 1; i != -1; i--)

{

p_MashIndex = (p_Height - 1 - i) * (_MashStride * 8);

_WriteIndex = i * p_NewBitmapData.Stride;

for (int z = 0; z != p_NewBitmapData.Width; z++)

{

byte _Index = p_FileBytes[p_ReadIndex];

Color _SetColor = (Color)_ColorHashTable[_Index.ToString()];

p_NewData[_WriteIndex + (z * 4)] = (byte)_SetColor.B;

p_NewData[_WriteIndex + (z * 4) + 1] = (byte)_SetColor.G;

p_NewData[_WriteIndex + (z * 4) + 2] = (byte)_SetColor.R;

p_NewData[_WriteIndex + (z * 4) + 3] = 0xFF;

if (_MashArray[p_MashIndex])p_NewData[_WriteIndex + (z * 4) + 3] = 0x00; //

p_ReadIndex++;

p_MashIndex++;

}

}

}

private void Load4(byte[] p_FileBytes, byte[] p_NewData, int p_ReadIndex, int p_Width, int p_Height, int p_MashIndex, BitmapData p_NewBitmapData)

{

int _WriteIndex = 0;

Hashtable _ColorHashTable = new Hashtable();

for (int i = 0; i != 16; i++)

{

_ColorHashTable.Add(i.ToString(), Color.FromArgb(p_FileBytes[p_ReadIndex + 3], p_FileBytes[p_ReadIndex + 2], p_FileBytes[p_ReadIndex + 1], p_FileBytes[p_ReadIndex]));

p_ReadIndex += 4;

}

p_MashIndex = (p_Width * p_Height / 2) + p_ReadIndex;

int _MashStride = p_Width / 8;

if (p_Width % 8 != 0) _MashStride++;

if (_MashStride % 4 != 0) _MashStride += _MashStride % 4;

byte[] _MashBytes = new byte[_MashStride * p_Height];

Array.Copy(p_FileBytes, p_MashIndex, _MashBytes, 0, _MashBytes.Length);

for (int i = 0; i != _MashBytes.Length; i++)

{

_MashBytes[i] = ConvertByte.OperateData.ReverseByte(_MashBytes[i]);

}

BitArray _MashArray = new BitArray(_MashBytes);

bool _Lith = true;

for (int i = p_NewBitmapData.Height - 1; i != -1; i--)

{

p_MashIndex = (p_Height-1 - i) * (_MashStride * 8);

_WriteIndex = i * p_NewBitmapData.Stride;

for (int z = 0; z != p_NewBitmapData.Width; z++)

{

byte _Index = p_FileBytes[p_ReadIndex];

if (_Lith)

{

_Index = (byte)((_Index & 0xF0) >> 4);

_Lith = false;

}

else

{

_Index = (byte)(_Index & 0x0F); //后面的F

_Lith = true;

p_ReadIndex++;

}

Color _SetColor = (Color)_ColorHashTable[_Index.ToString()];

p_NewData[_WriteIndex + (z * 4)] = (byte)_SetColor.B;

p_NewData[_WriteIndex + (z * 4) + 1] = (byte)_SetColor.G;

p_NewData[_WriteIndex + (z * 4) + 2] = (byte)_SetColor.R;

p_NewData[_WriteIndex + (z * 4) + 3] = 0xFF;

if (_MashArray[p_MashIndex])p_NewData[_WriteIndex + (z * 4) + 3] = 0x00; //

p_MashIndex++;

}

}

}

private void Load1(byte[] p_FileBytes, byte[] p_NewData, int p_ReadIndex, int p_Width, int p_Height, int p_MashIndex, BitmapData p_NewBitmapData)

{

int _WriteIndex = 0;

Hashtable _ColorHashTable = new Hashtable();

for (int i = 0; i != 2; i++)

{

_ColorHashTable.Add(i.ToString(), Color.FromArgb(p_FileBytes[p_ReadIndex + 3], p_FileBytes[p_ReadIndex + 2], p_FileBytes[p_ReadIndex + 1], p_FileBytes[p_ReadIndex]));

p_ReadIndex += 4;

}

p_MashIndex = (p_Width * p_Height /8) + p_ReadIndex;

int _MashStride = p_Width / 8;

if (p_Width % 8 != 0) _MashStride++;

if (_MashStride % 4 != 0) _MashStride += _MashStride % 4;

byte[] _MashBytes = new byte[_MashStride * p_Height];

Array.Copy(p_FileBytes, p_MashIndex, _MashBytes, 0, _MashBytes.Length);

for (int i = 0; i != _MashBytes.Length; i++)

{

_MashBytes[i] = ConvertByte.OperateData.ReverseByte(_MashBytes[i]);

}

BitArray _MashArray = new BitArray(_MashBytes);

int _Lith = 7;

for (int i = p_NewBitmapData.Height - 1; i != -1; i--)

{

p_MashIndex = (p_Height - 1 - i) * (_MashStride * 8);

_WriteIndex = i * p_NewBitmapData.Stride;

for (int z = 0; z != p_NewBitmapData.Width; z++)

{

byte _Index = p_FileBytes[p_ReadIndex];

BitArray _ColorIndex = new BitArray(new byte[] { _Index });

if (_ColorIndex[_Lith])

{

_Index = 1;

}

else

{

_Index = 0;

}

if (_Lith == 0)

{

p_ReadIndex++;

_Lith = 7;

}

else

{

_Lith--;

}

Color _SetColor = (Color)_ColorHashTable[_Index.ToString()];

p_NewData[_WriteIndex + (z * 4)] = (byte)_SetColor.B;

p_NewData[_WriteIndex + (z * 4) + 1] = (byte)_SetColor.G;

p_NewData[_WriteIndex + (z * 4) + 2] = (byte)_SetColor.R;

p_NewData[_WriteIndex + (z * 4) + 3] = 0xFF;

if (_MashArray[p_MashIndex])p_NewData[_WriteIndex + (z * 4) + 3] = 0x00; //

p_MashIndex++;

}

}

}

#endregion

private void LoadImgae(short m_Piex, byte[] p_FileBytes,int _StarIndex)

{

int _Width = m_CurHead.ImageWidth;

int _Height = m_CurHead.ImageHeight;

m_CurImage = new Bitmap(_Width, _Height, PixelFormat.Format32bppArgb);

BitmapData _NewBitmapData = m_CurImage.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

byte[] _NewData = new byte[_NewBitmapData.Stride * _NewBitmapData.Height];

int _ReadIndex = _StarIndex;

int _MashIndex = 0;

switch (m_Piex)

{

case 1:

_MashIndex = (_Width * _Height / 8) + _ReadIndex;

Load1(p_FileBytes, _NewData, _ReadIndex, _Width, _Height, _MashIndex, _NewBitmapData);

break;

case 4:

_MashIndex = (_Width * _Height / 2) + _ReadIndex;

Load4(p_FileBytes, _NewData, _ReadIndex, _Width, _Height, _MashIndex, _NewBitmapData);

break;

case 8:

_MashIndex = _Width * _Height + _ReadIndex;

Load8(p_FileBytes, _NewData, _ReadIndex, _Width, _Height, _MashIndex, _NewBitmapData);

break;

case 24:

_MashIndex = _Width * _Height * 3 + _ReadIndex;

Load24(p_FileBytes, _NewData, _ReadIndex, _Width, _Height, _MashIndex, _NewBitmapData);

break;

case 32:

_MashIndex = _Width * _Height * 4 + _ReadIndex;

Load32(p_FileBytes, _NewData, _ReadIndex, _Width, _Height, _MashIndex, _NewBitmapData);

break;

default:

throw new Exception("不支持的格式");

}

Marshal.Copy(_NewData, 0, _NewBitmapData.Scan0, _NewData.Length);

m_CurImage.UnlockBits(_NewBitmapData);

}

public void SaveImage(string p_FileName)

{

if (m_CurList.Count == 0) return;

FileStream _File = new FileStream(p_FileName, FileMode.Create, FileAccess.Write);

m_CurHead = new CurHead();

_File.Write(new byte[]{0x00,0x00,0x02,0x00},0,4);

_File.Write(BitConverter.GetBytes((ushort)m_CurList.Count),0,2);

List<byte[]> _ImageByteList = new List<byte[]>();

m_CurHead.ImageRVA = (uint)m_CurList.Count * 16+6;

for (int i = 0; i != m_CurList.Count; i++)

{

if (m_CurList[i].Width > 255 || m_CurList[i].Height > 255)

{

_File.Close();

throw new Exception("图形文件过大!");

}

byte[] _ImageSize = GetImageBytes(i);

m_CurHead.ImageHeight = (byte)CurImage[i].Height;

m_CurHead.ImageWidth = (byte)CurImage[i].Width;

m_CurHead.ImageRVA += m_CurHead.ImageLength;

m_CurHead.ImageLength = (uint)_ImageSize.Length;

_ImageByteList.Add(_ImageSize);

_File.Write(m_CurHead.GetImageByte(), 0, 16);

}

for (int i = 0; i != _ImageByteList.Count; i++)

{

byte[] _Height = BitConverter.GetBytes((uint)(m_CurList[i].Height * 2));

_ImageByteList[i][8] = _Height[0];

_ImageByteList[i][9] = _Height[1];

_ImageByteList[i][10] = _Height[2];

_ImageByteList[i][11] = _Height[3];

_File.Write(_ImageByteList[i], 0, _ImageByteList[i].Length);

}

_File.Close();

}

public MemoryStream SaveImage()

{

if (m_CurList.Count == 0) throw new Exception("无图形可保存");

MemoryStream _Memory = new MemoryStream();

m_CurHead = new CurHead();

_Memory.Write(new byte[] { 0x00, 0x00, 0x02, 0x00 }, 0, 4);

_Memory.Write(BitConverter.GetBytes((ushort)m_CurList.Count), 0, 2);

List<byte[]> _ImageByteList = new List<byte[]>();

m_CurHead.ImageRVA = (uint)m_CurList.Count * 16 + 6;

for (int i = 0; i != m_CurList.Count; i++)

{

if (m_CurList[i].Width > 255 || m_CurList[i].Height > 255)

{

_Memory.Close();

throw new Exception("图形文件过大!");

}

byte[] _ImageSize = GetImageBytes(i);

m_CurHead.ImageHeight = (byte)CurImage[i].Height;

m_CurHead.ImageWidth = (byte)CurImage[i].Width;

m_CurHead.ImageRVA += m_CurHead.ImageLength;

m_CurHead.ImageLength = (uint)_ImageSize.Length;

_ImageByteList.Add(_ImageSize);

_Memory.Write(m_CurHead.GetImageByte(), 0, 16);

}

for (int i = 0; i != _ImageByteList.Count; i++)

{

byte[] _Height = BitConverter.GetBytes((uint)(m_CurList[i].Height * 2));

_ImageByteList[i][8] = _Height[0];

_ImageByteList[i][9] = _Height[1];

_ImageByteList[i][10] = _Height[2];

_ImageByteList[i][11] = _Height[3];

_Memory.Write(_ImageByteList[i], 0, _ImageByteList[i].Length);

}

return _Memory;

}

/// <summary>

/// CUR图形

/// </summary>

public IList<Image> CurImage { get { return m_CurList; } set { m_CurList = value; } }

public byte[] GetImageBytes(int p_ImageIndex)

{

MemoryStream _Memory = new MemoryStream();

if (m_CurList[p_ImageIndex].PixelFormat != PixelFormat.Format32bppArgb)

{

Bitmap _Image = new Bitmap(m_CurList[p_ImageIndex].Width, m_CurList[p_ImageIndex].Height, PixelFormat.Format32bppArgb);

Graphics _Graphcis = Graphics.FromImage(_Image);

_Graphcis.Dispose();

_Image.Save(_Memory, ImageFormat.Bmp);

}

else

{

m_CurList[p_ImageIndex].Save(_Memory, ImageFormat.Bmp);

}

byte[] _Test = _Memory.ToArray();

byte[] _ImageBytes = new byte[_Memory.Length - 0x0E];

_Memory.Position = 0x0E;

_Memory.Read(_ImageBytes, 0, _ImageBytes.Length);

return _ImageBytes;

}

}

}

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新asp.net教程学习
热门asp.net教程学习
编程开发子分类