C# CUR类实现代码
程序员文章站
2024-03-09 12:39:53
复制代码 代码如下:using system; using system.collections.generic; using system.collections; us...
复制代码 代码如下:
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;
}
}
}