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; } } }
(编辑:焦作站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|