Copy codeThe Code is as follows: 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 file operation class
// 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>
/// Graphic height
/// </Summary>
Public byte ImageHeight {get {return m_ImageHeight;} set {m_ImageHeight = value ;}}
/// <Summary>
/// Number of images
/// </Summary>
Public ushort ImageCount {get {return BitConverter. ToUInt16 (m_ImageCount, 0);} set {m_ImageCount = BitConverter. GetBytes (value );}}
/// <Summary>
/// Image Width
/// </Summary>
Public byte ImageWidth {get {return m_ImageWidth;} set {m_ImageWidth = value ;}}
/// <Summary>
/// Number of colors (color less than 256)
/// </Summary>
Public byte ColorCount {get {return m_ColorCount;} set {m_ColorCount = value ;}}
/// <Summary>
/// The length of the image data block
/// </Summary>
Public uint ImageLength {get {return BitConverter. ToUInt32 (m_ImageLength, 0);} set {m_ImageLength = BitConverter. GetBytes (value );}}
/// <Summary>
/// The offset of the image data block to the file header
/// </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 ("unsupported format ");
}
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 [] {0 x, 0 x, 0 x );
_ 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 ("the graphic file is too large! ");
}
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 ("no image can be saved ");
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 ("the graphic file is too large! ");
}
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 Image
/// </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;
}
}
}